Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to expose a property (virtual field) on a Django Model as a field in a TastyPie ModelResource

I have a property in a Django Model that I'd like to expose via a TastyPie ModelResource.

My Model is

class UserProfile(models.Model):     _genderChoices = ((u"M", u"Male"), (u"F", u"Female"))      user = Models.OneToOneField(User, editable=False)     gender = models.CharField(max_length=2, choices = _genderChoices)      def _get_full_name(self):         return "%s %s" % (self.user.first_name, self.user.last_name)      fullName = property(_get_full_name) 

My ModelResource is

class UserProfileResource(ModelResource):     class Meta:         queryset = models.UserProfile.objects.all()         authorization = DjangoAuthorization()         fields = ['gender', 'fullName'] 

However all I'm currently getting out of the tastypie api is:

{     gender: 'female',     resource_uri: "/api/v1/userprofile/55/" } 

I have tried playing with the fields property in the ModelResource, but that hasn't helped. Would love to understand what is going on here.

like image 322
Danish Munir Avatar asked Jan 31 '12 10:01

Danish Munir


People also ask

How do I add a field to an existing model in Django?

To answer your question, with the new migration introduced in Django 1.7, in order to add a new field to a model you can simply add that field to your model and initialize migrations with ./manage.py makemigrations and then run ./manage.py migrate and the new field will be added to your DB.

Is there a list field for Django models?

Mine is simpler to implement, and you can pass a list, dict, or anything that can be converted into json. In Django 1.10 and above, there's a new ArrayField field you can use.

How do I create a custom field in Django?

Look at the existing Django fields (in django/db/models/fields/__init__.py ) for inspiration. Try to find a field that's similar to what you want and extend it a little bit, instead of creating an entirely new field from scratch. Put a __str__() method on the class you're wrapping up as a field.

How do you define choice fields in Django?

Choices can be any sequence object – not necessarily a list or tuple. The first element in each tuple is the actual value to be set on the model, and the second element is the human-readable name. Let us create a choices field with above semester in our django project named geeksforgeeks.


2 Answers

You should be able to define it as a field try:

class UserProfileResource(ModelResource):     fullname = fields.CharField(attribute='_get_full_name', readonly=True)     class Meta:         queryset = models.UserProfile.objects.all()         authorization = DjangoAuthorization()         fields = ['gender',] 

Edit

You also have to include: set readonly=True on your CharField, or TastyPie will try to set its value on insertion or update.

like image 132
JamesO Avatar answered Sep 24 '22 02:09

JamesO


A full example with dehydrate:

class UserResource(ModelResource):     fullname = fields.CharField(readonly=True)      class Meta:         queryset = auth_models.User.objects.all()         resource_name = 'user'      def dehydrate_fullname(self, bundle):         return u"{first_name} {last_name}".format(             first_name=bundle.obj.first_name, last_name=bundle.obj.last_name) 
like image 23
dzen Avatar answered Sep 25 '22 02:09

dzen