I am trying to post this json request through postman
{ "name":"Someones order",
"date_due": "2024-06-23T15:52:59Z",
"customer":3,
"orderItem":[{
"item":1,
"count":1
}]
}
I have implemented my models like so.
class Item(models.Model):
name = models.CharField(max_length=255)
price = models.DecimalField(max_digits=6, decimal_places=2)
bakery = models.ForeignKey(Bakery,on_delete=models.CASCADE,related_name='items')
def __str__(self):
return f'{self.name}'
class Order(models.Model):
name = models.CharField(max_length=255)
bakery = models.ForeignKey(Bakery,on_delete=models.CASCADE,related_name='orders')
customer = models.ForeignKey(Customer,on_delete=models.CASCADE,related_name='orders')
date_created= models.DateTimeField(auto_now_add=True)
date_due = models.DateTimeField()
date_updated = models.DateTimeField(auto_now=True)
#order_item = models.OneToOneField(OrderItem, on_delete=models.CASCADE,related_name='item_orderitems')
def __str__(self):
return f'{self.name}'
class OrderItem(models.Model):
bakery = models.ForeignKey(Bakery,on_delete=models.CASCADE,related_name='order_items')
count = models.IntegerField()
item = models.ForeignKey(Item, on_delete=models.CASCADE,related_name='item_orderitems')
order = models.OneToOneField(Order, on_delete=models.CASCADE,related_name='orderitems')
def __str__(self):
return f'{self.name}'
Serializer is implemented as
class OrderItemCreateSerializer(serializers.ModelSerializer):
class Meta:
model = OrderItem
fields = ['item','count']
class OrderCreateSerializer(serializers.ModelSerializer):
orderItem=OrderItemCreateSerializer(many=True)
class Meta:
model = Order
fields = ("name","date_due","customer","orderItem")
def create(self, validated_data):
print("create")
print(validated_data)
itemid=validated_data.pop("orderItem")
print(itemid)
bakery=self.context['request'].user.bakery
customer=validated_data.pop("customer")
print(customer)
print("validated_data")
print(validated_data)
order=Order.objects.create(bakery=bakery,customer=customer,**validated_data)
print("create 4")
for items in itemid:
print("create 5")
OrderItem.objects.create(bakery=bakery,order=order,**items)
print("create 6")
print("returning")
return order
When I make the post request i get
Got AttributeError when attempting to get a value for field orderItem
on serializer OrderCreateSerializer
.
The serializer field might be named incorrectly and not match any attribute or key on the Order
instance.
Original exception text was: 'Order' object has no attribute 'orderItem'.
I understand that Order
model do not have a field pointing to orderitem
but relation ship is rather reverse. But OrderCreateSerializer lists orderItem as a field.
I have implemented the same with a regular serializer instead of Modelserializer thinking that maybe it is complaining since it really is not part of the model.
But most important thing is that if you look at my print statements it prints "returning" and returns.
Should I implement the create method of the modelviewset and implement some of the logic there? would that help?
I would advise to stick to the framework features. The relation between Order
and Item
is m2m, since an extra fields is required, then its necessary to create a through table.
models.py
class Order(models.Model):
...
item_list = models.ManyToManyField(
Item,
through="OrderItem",
)
class OrderItem(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name="items")
item = models.ForeignKey(Item, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField()
serializers.py
class OrderItemSerializer(serializers.ModelSerializer):
class Meta:
model = OrderItem
fields = ["item", "quantity"]
class OrderSerializer(serializers.ModelSerializer):
items = OrderItemSerializer(many=True)
class Meta:
model = Order
fields = ("name", "bakery", "customer", "date_due", "items")
def create(self, validated_data):
items = validated_data.pop("items")
order = super().create(validated_data)
for obj in items:
obj.update({"order": order})
OrderItem.objects.create(**obj)
return order
payload (you missed bakery
key:value)
{
"name": "Someones order",
"date_due": "2024-06-23T15:52:59Z",
"bakery": 1,
"customer": 3,
"items": [
{
"item": 1,
"quantity": 1
}
]
}
And, unless a Bakery
has an unique item then having its FK in Item
is a waste.