Django nested serializer for multiple models, with linked foreignKeys


gegetinib

For example, let's use these 3 simple models. A city can have multiple stores, and a store can have multiple products

models.py

class City(models.Model):
    name=models.CharField(max_length=300)

class Shop(models.Model):
    name = models.CharField(max_length=300)
    city = models.ForeignKey(City, related_name='related_city', on_delete=models.CASCADE)

class Product(models.Model):
    name=models.CharField(max_length=300)
    shop=models.ForeignKey(Shop, related_name='related_shop', on_delete=models.CASCADE)

serializers.py

class CitySerializer(serializers.ModelSerializer):
    class Meta:
        model = City
        fields=['id','name']

class ShopSerializer(serializers.ModelSerializer):
    related_shop = CitySerializer(many=True, read_only=True)
    class Meta:
        model = Shop
        fields=['id','name','related_city']

class ProductSerializer(serializers.ModelSerializer):
    related_shop = ShopSerializer(many=True, read_only=True)
    class Meta:
        model = Product
        fields=['id','name','related_shop']

In get_queryset() in views.py, I am using .select_related(). all() to get foreign objects. ProductSerializer will give me all the products and will get the ForeignKey store and I will also get the name of the store where the product was found.

The ShopSerializer will similarly give me all the store names and all the cities where the store can be found.

But how can I make a serializer that can retrieve from all 3 tables at the same time? The fields I want are: fields = ['product_name', 'shop_name', 'city_name']

I know, that the list I will get will be repetitive and can be considered as 1NF or 2NF, as opposed to the model design I did as 3NF for the database. But that's the query I want.

I'm actually thinking of denormalizing the database so I can easily achieve this.

My second question is, is it better to normalize it to 1NF and have repeatability in order to reduce CPU-intensive inner joins between these 3 tables on 'id'? I've done a lot of research on this and the usual lazy answer is: try both variants, benchmark and decide for yourself.

Guerrilla

Your problem will have a different approach. Immediately fetching the relevant object from the database doesn't actually depend on the serializer itself. This is done in the view layer, where you can add select_related('shop__city')to the queryset. By appending this, you are preloading both shopthe shop.cityvalue and the value onto the object in a single query .Product

An easy way to serialize these fields is to set them in the serializer field sourcelike this:

class ProductSerializerV2(serializers.ModelSerializer):
    shop_name = serializers.CharField(source='shop.name')
    city_name = serializers.CharField(source='shop.city.name')

    class Meta:
        model = Product
        fields = ['name', 'shop_name', 'city_name']

in conclusion

Based on the description above, the code snippet below will make only one query to the database

p = Product.objects.select_related('shop__city').last()
print(ProductSerializerV2(p).data)  
# {'name': 'product-z', 'shop_name': 'shop-z', 'city_name': 'z'} as a sample output

Related


Django nested serializer does not serialize inner models

Joseph Kerber I'm trying to add customizations to me in Django2 using . The problem is that my serializer doesn't serialize the nested model, so it gives me the error:actionViewSetdjango-rest-framework { "labels": [ { "non_field_errors"

Django: Serialize a list of multiple linked models

Waldemar Edward Sandel Rolfson Given two different models, they have the same parent base class. Is it possible to serialize a linked list containing instances of two child models using the Django Rest Framework serializer or serpy? Given some example models:

Django: Serialize a list of multiple linked models

Waldemar Edward Sandel Rolfson Given two different models, they have the same parent base class. Is it possible to serialize a linked list containing instances of two child models using the Django Rest Framework serializer or serpy? Given some example models:

Django: Serialize a list of multiple linked models

Waldemar Edward Sandel Rolfson Given two different models, they have the same parent base class. Is it possible to serialize a linked list containing instances of two child models using the Django Rest Framework serializer or serpy? Given some example models:

Django: Serialize a list of multiple linked models

Waldemar Edward Sandel Rolfson Given two different models, they have the same parent base class. Is it possible to serialize a linked list containing instances of two child models using the Django Rest Framework serializer or serpy? Given some example models:

Django: Serialize a list of multiple linked models

Waldemar Edward Sandel Rolfson Given two different models, they have the same parent base class. Is it possible to serialize a linked list containing instances of two child models using the Django Rest Framework serializer or serpy? Given some example models:

Django: Serialize a list of multiple linked models

Waldemar Edward Sandel Rolfson Given two different models, they have the same parent base class. Is it possible to serialize a linked list containing instances of two child models using the Django Rest Framework serializer or serpy? Given some example models:

django rest framework nested fields with multiple models

Momokjaaaaa This is django and django rest framework. I have 2 models: User and Phone. first question: I want to be able to update user data (email) as well as phone data (phone number) in 1 api update response. Phone numbers can be 0 or many. Well, it's actua

Django insert performance with multiple nested models

Thanh Nguyen I have the following model definition: class Workflow(models.Model): name = models.CharField(max_length=255) class Step(models.Model): workflow = models.ForeignKey(Section, on_delete=models.CASCADE, related_name='steps') title = model

Django - Handling multiple nested models at different levels

CH Andre Meloa I have some questions about Django nested models. As far as I know, to handle nested data structures, I have to deserialize each data and then create objects that will be concatenated with the ForeignKeyField. I can handle this by overriding the

django rest framework nested fields with multiple models

Momokjaaaaa This is django and django rest framework. I have 2 models: User and Phone. first question: I want to be able to update user data (email) as well as phone data (phone number) in 1 api update response. Phone numbers can be 0 or many. Well, it's actua

django rest framework nested fields with multiple models

Momokjaaaaa This is django and django rest framework. I have 2 models: User and Phone. first question: I want to be able to update user data (email) as well as phone data (phone number) in 1 api update response. Phone numbers can be 0 or many. Well, it's actua

Django insert performance with multiple nested models

Thanh Nguyen I have the following model definition: class Workflow(models.Model): name = models.CharField(max_length=255) class Step(models.Model): workflow = models.ForeignKey(Section, on_delete=models.CASCADE, related_name='steps') title = model