I want save the category and their subcategories to the database and here each category have a multiple subcategories.Could you please help me to save the user,category and multiple subcategories corresponding to category.Models.py, Serializers.py, Views.py and incomming request is attached.
Models.py
class SavingCategoryandPreferences(models.Model):
user = models.ForeignKey(User, related_name='user')
news_category = models.ForeignKey(NewsCategory)
subcategories= models.ManyToManyField(NewsSubCategory, related_name='sub')
sort_order = models.IntegerField(default=0)
slug = AutoSlugField(populate_from='subcategories_id', separator='', editable=True)
created_time = models.DateTimeField("Created Date", auto_now_add=True)
Serializers.py
class MobilecatsubSerializer(serializers.ModelSerializer):
class Meta:
model = SavingCategoryandPreferences
fields = ('id', 'user', 'subcategories', 'news_category',)
Views.py
class MobileCatsubViewswt(viewsets.ModelViewSet):
serializer_class = serializers.MobilecatsubSerializer
queryset = SavingCategoryandPreferences.objects.all()
Incomming Request
{
"user":"39",
"news_category":"22",
"subcategories": [
{"sub_id":"1"},
{"sub_id":"2"}
]
}
By default DRF serializers.ModelSerializer
defines all related fields as PrimaryKeyRelatedField
. For to-many relationships ( many=True
) ie reverse FK or many-to-many, it implicitly creates an instance of ManyRelatedField
with the original field ( PrimaryKeyRelatedField
in this case) kept as the child_relation
instance attribute, which in turn is used in the to_internal_value
method of ManyRelatedField
to actually do validation for each incoming item (primary keys in this case) passed in as list elements for the field.
The above is a long way of saying that you can only pass the primary keys of the related NewsSubCategory
instances in a list eg:
{
"user":"39",
"news_category":"22",
"subcategories": [1, 2]
}
You can even pass the primary keys as strings.
Now, if you don't have any control over how and in what format the data is passed, you can override to_internal_value
method of MobilecatsubSerializer
to extract the primary keys from the input data and update the input data dict
with them eg:
class MobilecatsubSerializer(serializers.ModelSerializer):
class Meta:
model = SavingCategoryandPreferences
fields = ('id', 'user', 'subcategories', 'news_category',)
def to_internal_value(self, data):
if 'subcategories' in data:
# Change this if needed
spams = [dct['sub_id'] for dct in data['subcategories']]
data.update(subcategories=subcategories)
return super().to_internal_value(data)
If you feel overly ambitious you can go ahead and instead override the to_internal_value
method of the PrimaryKeyRelatedField
(or anything you use for the field) to do the serialization of the values there, but it would be a bad idea as all other serializers that have PrimaryKeyRelatedField
also needs to go through this needlessly. But if for some reason, you want to follow this path, it would better to subclass PrimaryKeyRelatedField
, do serialization overriding to_internal_value
like the way I did above, and set this one explicitly as the serializer for the subcategories
field.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.