I’m looking for a way to use the Django ORM to perform a complex query on loosely related objects where the search is for an object that is a type of other object.
What if the Cart in our Ultimate Django course is a type of Container and you want a queryset containing the Cart and all of its items. Using the models below, how do you get the desired result without generating thousands of queries?
Example:
The query in following ViewSet with relating serializers get the desired result but produces thousands of queries:
class CartViewSet(ModelViewSet):
http_method_names = [‘get’,]
queryset = Cart.objects.prefetch_related(‘owner__user’).select_related(‘container’).select_related(‘owner’).all()
serializer_class = CartSerializer
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = [‘id’, ‘nickname’, ‘first_name’, ‘last_name’]
first_name = serializers.SerializerMethodField('get_first_name')
last_name = serializers.SerializerMethodField('get_last_name')
def get_first_name(self, profile: UserProfile):
return profile.user.first_name
def get_last_name(self, profile: UserProfile):
return profile.user.last_name
class ContainerItemProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = [‘id’, ‘name’, ‘description’, ‘price’]
class CartItemSerializer(serializers.ModelSerializer):
class Meta:
model = ContainerItem
fields = [‘id’, ‘product’]
thought = ContainerItemProductSerializer()
class CartContainerSerializer(serializers.ModelSerializer):
class Meta:
model = Container
fields = [
‘id’,
‘tag’,
‘created_at’,
‘items’,
]
items = CartContainerSerializer(many=True, read_only=True)
class CartSerializer(serializers.ModelSerializer):
class Meta:
model = Cart
fields = [
‘id’,
‘owner’,
‘container’,
]
owner = CartOwnerSerializer()
container = CartContainerSerializer()
[ MODELS ]
class Product(models.Model):
name = models.CharField()
description = models.TextField()
price = models.DecimalField()
class Container(models.Model):
tag = models.CharField()
created_at = models.DateTimeField()
class Cart(models.Model):
owner = models.ForeignKey(UserProfile)
container = models.OneToOneField(Container)
class ContainerItem(models.Model):
container = models.ForeignKey(Container)
item = models.ForeignKey(Product)
quantity = PositiveSmallIntegerField()