gpt4 book ai didi

sql - 具有许多相同 ID 的 Django ManyToManyField

转载 作者:行者123 更新时间:2023-12-05 00:45:09 25 4
gpt4 key购买 nike

我正在尝试在 Django 中制作一个简单的披萨订购应用程序。我有 3 个模型(浇头、比萨饼、订单)。在订单模型中有 ManyToManyField 到 Pizza。如果“用户”为每个比萨饼订购一个(例如玛格丽塔和意大利辣香肠),则工作正常,但如果在 POST 请求中订购 2 个玛格丽塔,我的结果中只有一个玛格丽塔 ID。我如何在一个订单中传递 n 个比萨饼?

我的模型看起来像这样:

class Toppings(models.Model):
name = models.CharField(blank=False, max_length=100, unique=True)

class Meta:
ordering = ['name']

def __str__(self):
return self.name


class Pizza(models.Model):
name = models.CharField(blank=False, max_length=100, unique=True)
ingredients = models.ManyToManyField(Toppings, blank=False, null=False)

class Meta:
ordering = ['name']

def __str__(self):
return self.name


class PizzaOrder(models.Model):
created = models.DateTimeField(auto_now_add=True)
items = models.ManyToManyField(Pizza, blank=False, null=False)
status = models.CharField(max_length=1, choices=[
(1, 'placed'),
(2, 'approved'),
(3, 'cooked'),
(4, 'delivered'),
(5, 'canceled')
], default=1)

class Meta:
ordering = ['created']

def __str__(self):
return self.created

我用这个数据发送POST:
{
"items": [1, 1, 1, 2, 2],
"status": 1
}

并且在项目列表中只有 1 和 2(不是 1,1,1,2,2):
{
"id": 2,
"items": [
1,
2
],
"status": 1
}

序列化程序和订单 View
class OrdersSerializer(serializers.ModelSerializer):

class Meta:
model = PizzaOrder
fields = ['id', 'items', 'status', 'created']


class PizzaOrdersList(ModelViewSet):
queryset = PizzaOrder.objects.all()
serializer_class = OrdersSerializer

最佳答案

直通模型非常适合这种情况。 ManyToManyFields在后台创建这种数据库关系,只会创建Pizza和PizzaOrder的独特组合,但您可以轻松实现自己。

只需创建一个名为 PizzaOrderItem 的类,其中包含 ForeignKeys到 Pizza 和 PizzaOrder 模型:

class PizzaOrderItem(models.Model):
pizza = ForeignKey(Pizza)
pizza_order = ForeignKey(PizzaOrder)

然后,您可以更改 ManyToManyField 以使用您通过模型创建的自定义:
class PizzaOrder(models.Model):
...
items = models.ManyToManyField(Pizza, through='<your_app_name>.PizzaOrderItem',
blank=False,
null=False)
...

您甚至可以向您的直通模型添加额外的字段,例如浇头或数量,如下所示:
class PizzaOrderItem(models.Model):
pizza = ForeignKey(Pizza)
pizza_order = ForeignKey(PizzaOrder)

toppings = ManyToManyField(Toppings)
quantity = IntegerField(default=1)

您可以通过 order.items 订购比萨饼和实际通过模型对象通过 order.pizza_order_item_set .

序列化器

检索订单的项目非常简单。
正确展示您的新 PizzaOrderItems ,您需要添加一个序列化程序,并在 PizzaOrderSerializer 上设置项目使用您的新序列化程序:
class PizzaOrderItemSerializer(serializer.ModelSerializer):
class Meta:
model = PizzaOrderItem
# If you add a field like quantity you can add them to the fields list below.
fields = ['pizza', 'pizza_order']


class PizzaOrderSerializer(serializer.ModelSerializer):
items = PizzaOrderItemSerializer(source='pizza_order_item_set', many=True)

class Meta:
model = PizzaOrder
fields = ['id', 'items', 'status', 'created']

创建 PizzaOrderItems

有两种方法可以创建 PizzaOrderItems。第一个非常简单。只需创建一个类似于 PizzaOrder 的 View ,并使用 PizzaOrderItemSerializer :
class PizzaOrderItemViewSet(generics.ListCreateAPIView):
queryset = PizzaOrderItem.objects.all()
serializer_class = PizzaOrderItemSerializer

然后,您可以使用 POST 数据为订单创建项目:
{
"pizza" : <pizza_id_here>
"pizza_order" : <pizza_order_id_here>
}

第二种方法是仅使用 PizzaOrder View ,并将创建函数覆盖到 PizzaOrder 序列化程序。这是因为嵌套序列化器默认是只读的,所以我们在这里做的是覆盖根序列化器的 create 方法,并使用嵌套序列化器的验证数据创建子对象。
class PizzaOrderSerializer(serializer.ModelSerializer):
...

def create(self, validated_data):
items = validated_data.pop('items')
order = PizzaOrder.objects.create(**validated_data)
for item_data in items:
PizzaOrderItem.objects.create(pizza_order=order, **item_data)
return order

如果您使用此方法,您可以使用 POST 数据创建订单:
{
"items": [
{ "pizza" : 1 },
{ "pizza" : 1 },
{ "pizza" : 2 },
{ "pizza" : 2 },
]
"status": 1
}

关于sql - 具有许多相同 ID 的 Django ManyToManyField,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58537710/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com