Reputation: 624
Given these models:
class Product(models.Model):
name = CharField(max_length=255)
class Order(models.Model):
product = models.ForeignKey(Product)
user = models.ForeignKey(User)
quantity = models.PositiveIntegerField()
A user can only have a single Order object per product. I would like an API call to show a list of products, with the user's order where available. Is there a way to do that?
The default serialisation lists ALL orders under order_set
. I did get a bit ahead with this to filter by user:
class FilteredOrderSerializer(serialisers.ListSerializer):
def to_representation(self, data):
data = data.filter(user=self.context['request'].user)
return super(FilteredOrderSerializer, self).to_representation(data)
class OrderSerializer(serializers.ModelSerializer):
class Meta:
model = Order
list_serializer_class = FilteredOrderSerializer
class ProductSerializer(serializers.ModelSerializer):
order_set = OrderSerializer(many=True, read_only=True)
class Meta:
model = Product
So now it only shows the authenticated user's order, but the resulting JSON looks something like
[
{
"name": "prod1",
"order_set": [
{
"quantity": 4
}
],
}
]
i.e. the field is still called order_set
and it's a list, while I would like it to be called order
and be either an object or null. So I'm not sure where this filtering should take place, nor how to define the field.
Edit: I'm using a simple viewset
class ProductViewSet(view sets.ReadOnlyModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
Upvotes: 2
Views: 1445
Reputation: 4643
You need to add related_name field in your orders so you can
product.orders.all()
Then this should do.
class Order(models.Model):
product = models.ForeignKey(Product, related_name='orders')
user = models.ForeignKey(User)
quantity = models.PositiveIntegerField()
class ProductSerializer(serializers.ModelSerializer):
order = serializers.SerializerMethodField()
class Meta:
model = Product
fields = ('name', 'order')
def get_order(self, object):
try:
order = object.orders.get(user=self.context['request'].user)
return SceneDetailSerializer(order).data
except Order.DoesNotExist:
return None
Update: You can try out serializer method field. Not sure if self contains context and user references in it. You need to remove listfield from your order serializer. Let me know if it works.
Upvotes: 2