我该如何处理保存外键?

时间:2013-02-28 11:13:10

标签: django foreign-keys

我有两个模型OrderOrderItem

class OrderItem(SmartModel):
    shopping_id = models.CharField(max_length=50,db_index=True)
    quantity = models.IntegerField(default=0)
    item = models.ForeignKey(Item)
    order = models.ForeignKey(Order)

这就是创建和保存OrderItem对象

的方法
if not item_in_orders:
        # creat and save a new order item
        anon_user = User.objects.get(id=settings.ANONYMOUS_USER_ID) 
        try:
            order= Order.objects.get(pk=order_id)
        except:
            order = Order.objects.create(created_by=anon_user,modified_by=anon_user)

        oi=OrderItem.objects.create(order=order,shopping_id=_shopping_id(request),
                                          quantity=quantity,
                                          item=i,
                                          created_by=anon_user,
                                          modified_by=anon_user)
        oi.save()

现在我应该提到上面的OrderItem对象是在Order对象之前创建的。

class Order(SmartModel):
    email = models.EmailField(max_length=50,help_text="Needed as alternative")
    mobile = PhoneNumberField(max_length=20,default='+2507####')
    billing_name= models.CharField(max_length=50)
    billing_address= models.CharField(max_length=50)    
    billing_city = models.CharField(max_length=50)

这两个模型都是ModelForms,并且经过验证,除了在创建两个模型时,为Order创建了数据库中的两行。我怀疑未填充的第一行是在创建OrderItem时由此代码创建的。

order = Order.objects.create(created_by=anon_user,modified_by=anon_user)

            oi=OrderItem.objects.create(order=order,shopping_id=_shopping_id(request),
                                              quantity=quantity,
                                              item=i,
                                              created_by=anon_user,
                                              modified_by=anon_user)
            oi.save()

第二行是在我保存Order对象时创建的,并且没问题。

请记住,OrderItem之前创建Order,后者是前者的外键字段。

我对django应用程序的要求是在客户(在我的情况下为Order)之前创建订单商品。欢迎任何其他想法。

3 个答案:

答案 0 :(得分:0)

好的,如你所说

请记住,OrderItem是在Order之前创建的,而后者是在前者中的foreignkey字段。

然后在这种情况下,您应该设计您的模型,如

class OrderItem(SmartModel):
    shopping_id = models.CharField(max_length=50,db_index=True)
    quantity = models.IntegerField(default=0)
    item = models.ForeignKey(Item)
    order = models.ForeignKey(Order,blank=True,null = True)

我在这里告诉你如何在表格中保存Foreign key

在查询中

order = Order.objects.create(created_by=anon_user,modified_by=anon_user)

            oi=OrderItem.objects.create(order=order,shopping_id=_shopping_id(request),
                                              quantity=quantity,
                                              item=i,
                                              created_by=anon_user,
                                              modified_by=anon_user)
            oi.save()

我不知道什么是i但是如果要保存外键,那么i必须是Item的实例

我只是假设一个简单的例子,假如你首先从表单中获取itemname,你必须在Item表中过滤它。

getitem = Item.objects.get(name= itemname)

然后你可以保存你的外键,如

order = Order.objects.create(created_by=anon_user,modified_by=anon_user)

            oi=OrderItem.objects.create(order=order,shopping_id=_shopping_id(request),
                                              quantity=quantity,
                                              item=getitem,
                                              created_by=anon_user,
                                              modified_by=anon_user)
            oi.save()

答案 1 :(得分:0)

看起来你是

  1. 创建空白订单以使用OrderItem保存(以满足外键)
  2. 创建OrderItem后创建另一个完全填充的Order(因为您提到Order在OrderItem之后创建)。我假设,上面的代码中没有显示。
  3. 这就是您看到正在创建两个Order实例的原因。

    您可以第二次(步骤2)更新您在步骤1中创建的订单,而不是第二次创建新订单(例如电子邮件,地址等)并保存。

    编辑:添加了详细的操作方法......

    您的代码中会有一些位置用于创建第二个订单。不要在那里创建新订单,而是使用对步骤1中创建的订单的引用(您发布的代码中的订单变量),一旦可用就用电子邮件和地址信息更新它,并在其上调用save()。这将更新数据库中的顺序,而不是创建新实例。

答案 2 :(得分:0)

order = Order.object.create(
    created_by=anon_user, 
    modified_by=anon_user
    )


OrderItem.object.create(
    order = order, 
    shopping_id = _shopping_id(request),
    quantity=quantity,
    item=i,
    created_by=anon_user,
    modified_by=anon_user
    )

//To access the order after saving the above info
//For example:

order.email = 'anyone@gmail.com'
order.save()