Restricted set of nested fields in a django REST framework ModelSerializer - django

Consider the following serializer
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = ('id', 'account')
depth = 1
The field account refers to a ForeignKey in MyModel and I want to expose some of the Account fields with this serializer but not all of them.
How do I specify that only account.name and account.email should be serialized?

You can do this by creating your own serializer to use as the nested serializer.
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ('name', 'email', )
You are better off with creating specialized serializers instead of relying on Django REST Framework to create them for you. By default, serializers that are automatically created contain all fields defined on the model.
class MyModelSerializer(serializers.ModelSerializer):
account = AccountSerializer()
class Meta:
model = MyModel
fields = ('id', 'account', )
You can find out more about nested serializers in the Django REST Framework documentation.

Related

Get only one filed from a nested serializer

Her it is my django serializer:
class ShopSerializer(serializers.ModelSerializer):
rest = RestSerializer(many=True)
class Meta:
model = RestaurantLike
fields = ('id', 'created', 'updated', 'rest')
This will wrap whole RestSerializer inside ShopSerializer on response.
How can I get only one or two fields from RestSerializer instead of having all the fields inside ShopSerializer?
Get only two field of RestSerializer instead of whole RestSerializer
If you want to have limited amount of fields from RestSerializer, then you can simply limit it in the fields:
class RestSerializer(serializers.ModelSerializer):
class Meta:
model = Restaurant
fields = ('id', 'name', ...)
If you want just want field, lets say the primary key or Slug, then you can use PrimaryKeyRelatedField or SlugRelatedField for that. For example:
class ShopSerializer(serializers.ModelSerializer):
rest = serializers.SlugRelatedField(
many=True,
read_only=True,
slug_field='name'
)
class Meta:
model = RestaurantLike
fields = ('id', 'created', 'updated', 'rest')

Django Rest Framework -Serializer inside serializer using same instance

So, I have a weird legacy issue where I have one model "Data", and for serialization purposes I need to restructure the fields.
class Data(models.Model):
id ...
field_a
field_b
field_c
date
Then I have the serializers:
class DataInfoSerializer(ModelSerializer):
class Meta:
model = Data
fields = ['field_a', 'field_b', 'field_c']
class DataSerializer(ModelSerializer):
data_info = DataInfoSerializer(required=False, read_only=True)
class Meta:
model = Data
fields = ['id', 'date', 'data_info']
Now I somehow have to get DRF to use the same instance of Data that is passed into the "DataSerializer" to render the DataInfoSerializer.
Any ideas how to achieve this? Or a better way.
Use source='*' to pass the entire object to a field, including nested serializers. Docs
class DataSerializer(ModelSerializer):
data_info = DataInfoSerializer(required=False, read_only=True, source='*')
class Meta:
model = Data
fields = ['id', 'date', 'data_info']

Django multiple Admin Model

I Wanna use 2 Admin apps such as :
django-admin-sortable
django-import-export
Is there a way to use both in Admin Form ?
I mean my code is using SortableAdmin:
class RuleAdminForm(forms.ModelForm):
content = forms.CharField(widget=CKEditorWidget())
class Meta:
model = Rule
fields = '__all__'
class RuleAdmin(SortableAdmin):
list_display = ('title', 'section', 'subsection',)
readonly_fields = ('author', 'date_posted')
fields = ('title', 'section', 'subsection', 'content', 'author', 'date_posted')
form = RuleAdminForm
with .register(Rule, RuleAdmin)
If I want to use import-export I need to create this :
class RuleResource(resources.ModelResource):
class Meta:
model = Rule
class RuleResourceAdmin(ImportExportModelAdmin):
resource_class = RuleResource
But I can't register with .register(Rule, RuleResourceAdmin) since Rule is already registered
Is there a way to have both options ? Using sortable admin to sort my rules, and the possibility to import CSV etc.
Many thanks !
Using of proxy model.
class RuleProxyModel(Rule):
class Meta:
proxy = True
admin.site.register(RuleProxyModel,RuleResourceAdmin)
How to use proxy model

Storing multiple values in django model though serializer

I am fairly new to django rest framework. I have these tables in my database:
1) MainCategroies - which stores a list of all education fields.
2) College - which stores list of all college of my state.
3) CollegeCategoryLink - which stores the link between colleges and the categories to which they belong( here same college can fall under multiple categories). created a model with two foreign-key column
4) Users - the users of my app.
5) UserCategoryLink - link between the users and their selected categories. created a model with two foreign-key column
6) UserCollegeLink - link between the users and their selected colleges. created a model with two foreign-key column
Now the users will select their preferable categories from the list
and that will be stored in my database and then i will return the
related colleges back. All the data will come in json format from my
ionic app.
i have written serializers for each model and created viewsets for CRUD operations. Now i am confused, how to store the data through viewset methods? I am currently doing this:
class UserCategoryLinkViewset(viewsets.ViewSet):
serializer_class = UserCategoryLinkSerializer
def create(self, request):
selectedCats = []
collegeList = []
data = JSONParser().parse(request)
for field in data:
selectedCats.append(field['cat'])
ucl = UserCategoryLink()
ucl.user = collegeAppUser.objects.get(id=field['user'])
ucl.cat = MainCategories.objects.get(id=field['cat'])
if not UserCategoryLink.objects.filter(user=field['user'], cat=field['cat']).exists():
ucl.save()
for cats in selectedCats:
queryset = CollegeCategoryLink.objects.filter(category_id=cats)
serializer = CollegeCategoryLinkSerializer(queryset, many=True)
for clg in serializer.data:
queryset_college = College.objects.filter(id=clg['college_id'])
serializer_college = CollegeSerializer(queryset_college, many=True)
collegeList.append(serializer_college.data)
return JSONResponse(collegeList)
And here are my serializers:
from rest_framework import serializers
from manageApp.models import collegeAppUser,MainCategories,UserCategoryLink, CollegeCategoryLink, College, UserCollegeLink
class collegeAppUserSerializer(serializers.ModelSerializer):
class Meta:
model = collegeAppUser
fields = ('id', 'username', 'password')
class MainCategorySerializer(serializers.ModelSerializer):
class Meta:
model = MainCategories
fields = ('id', 'category_name')
class UserCategoryLinkSerializer(serializers.ModelSerializer):
class Meta:
model = UserCategoryLink
fields = ('id', 'user', 'cat')
class CollegeCategoryLinkSerializer(serializers.ModelSerializer):
class Meta:
model = CollegeCategoryLink
fields = ('id', 'college_id', 'category_id')
class CollegeSerializer(serializers.ModelSerializer):
class Meta:
model = College
fields = ('id', 'college_name', 'college_url')
class UserCollegeLinkSerializer(serializers.ModelSerializer):
class Meta:
model = UserCollegeLink
fields = ('id', 'user', 'college')
But this is not the correct way to accomplish what i need to do as i am directly setting the data in my model and saving it, no use of serializer in here. I want to store the data through serializer rather then directly using my model.
Try to relate models.
You can see the rest framework documentation: Relations!
For your case, you would use Nested relationships! =]

Django Rest Framework - image url on reverse foreignkey

I am trying to access the url of an ImageField on a model related through a reverse-ForeignKey. I have attempted various possible options based on examples in the docs, but have had no luck. Any help would be appreciated.
models.py
class Car(models.Model):
name = models.CharField(... )
#property
def default_image(self):
... ...
return image # <=== returns from the CarImage model
class CarImage(models.Model):
car = models.ForeignKey(Car) # <=== no related_name set, but technically we could use carimage_set
image = models.ImageField(... ...)
serializers.py (attempt)
class CarSerializer(serializers.ModelSerializer):
... ...
image = fields.SerializerMethodField('get_image')
class Meta:
mode = Car
def get_image(self, obj):
return '%s' % obj.default_image.url
exception
'SortedDictWithMetadata' object has no attribute 'default_image'
The new DRF 2.3 seems to be helpful with reverse relationships and has solved my issues.
DRF 2.3 Announcement
For example, in REST framework 2.2, reverse relationships needed to be included explicitly on a serializer class.
class BlogSerializer(serializers.ModelSerializer):
comments = serializers.PrimaryKeyRelatedField(many=True)
class Meta:
model = Blog
fields = ('id', 'title', 'created', 'comments')
As of 2.3, you can simply include the field name, and the appropriate serializer field will automatically be used for the relationship.
class BlogSerializer(serializers.ModelSerializer):
"""Don't need to specify the 'comments' field explicitly anymore."""
class Meta:
model = Blog
fields = ('id', 'title', 'created', 'comments')