【问题标题】:Django ORM save multiple forms at onceDjango ORM一次保存多个表单
【发布时间】:2015-05-25 13:35:01
【问题描述】:

我有一个关于一次保存三个表单的问题。前两个表单保存正常,没有问题,但第三个表单必须在 form2 保存到数据库时从 form2 请求 id。不知道这个程序哪里有问题,哪里出错了。

models.py

class Product_service(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255, blank=True, null=True)
    selling_price = models.DecimalField(decimal_places=5, max_digits=255, blank=True, null=True)
    purchase_price = models.DecimalField(decimal_places=5, max_digits=255, blank=True, null=True)
    description = models.CharField(max_length=255, blank=True, null=True)
    image = models.FileField(upload_to="/", blank=True, null=True)
    product_code = models.CharField(max_length=255, blank=True, null=True)
    product_code_supplier = models.CharField(max_length=255, blank=True, null=True)
    product_code_buyer = models.CharField(max_length=255, blank=True, null=True)
    min_unit_state = models.CharField(max_length=255, blank=True, null=True)
    state = models.CharField(max_length=255, blank=True, null=True)
    vat_id = models.ForeignKey('VatRate', related_name='vat_rate')
    unit_id = models.ForeignKey('Units', related_name='unit_value')
    category_id = models.ForeignKey('Category', related_name='product_services', blank=True, null=True)

    def __str__(self):
        return self.name

这个模型代表form2。

class InvoiceProdService(models.Model):
    id = models.AutoField(primary_key=True)
    invoice_id = models.ForeignKey('OutgoingInvoice', related_name='outgoing_invoice', blank=True, null=True)
    prod_serv_id = models.ForeignKey('Product_service', related_name='product_services', blank=True, null=True)
    code      = models.IntegerField(blank=True, null=True)
    prod_serv_name = models.CharField(max_length=255,blank=True, null=True)
    description = models.CharField(max_length=255,blank=True, null=True)
    rate_name   = models.CharField(max_length=255,blank=True, null=True)
    units = models.CharField(max_length=255, blank=True, null=True)
    price = models.DecimalField(decimal_places=5, max_digits=255, blank=True, null=True)
    vat   = models.DecimalField(decimal_places=5, max_digits=255, blank=True, null=True)
    current_vat = models.DecimalField(decimal_places=5, max_digits=255, blank=True, null=True)
    price_no_vat = models.DecimalField(decimal_places=5, max_digits=255, blank=True, null=True)


    def __str__(self):
        return self.id

这个模型代表form3。 其中两个字段与 Form2 的 ForeignKey 有关系。

  1. invoice_id = models.ForeignKey('OutgoingInvoice', related_name='outgoing_invoice', blank=True, null=True)

  2. prod_serv_id = models.ForeignKey('Product_service', related_name='product_services', blank=True, null=True)

当我尝试使用管理界面时,我可以将表单直接保存到数据库。而且效果很好。

views.py

这里是保存方法中的逻辑:

if request.method == 'POST':

        form1 = InsertNewCustomer(request.POST, prefix='form1')
        form2 = Outdrew(request.POST, prefix='form2')
        form5 = MultiplyInsertValues(request.POST, prefix='form5')

        if (form1.is_valid() and form2.is_valid() and form5.is_valid()):

            a, created = OrganizationInfo.objects.get_or_create(**form1.cleaned_data)

            if created:
                b = form2.save(commit=False)
                b.user_id = user_pk
                b.organization_id = org_id.id
                b.customer_id = a
                b.save()
                c = form5.save(commit=False)
                nesto = Product_service.objects.get(name= form5.cleaned_data['prod_serv_name'])
                c.prod_serv = nesto.id
                c.save()
                return HttpResponseRedirect('/izlazni_racuni/')
            else:
                b = form2.save(commit=False)
                organ_id = OrganizationInfo.objects.get(oib=form1.cleaned_data['oib'])
                b.user_id = user_pk
                b.organization_id = org_id.id
                b.customer_id = organ_id.id
                b.save()
                c = form5.save(commit=False)
                nesto = Product_service.objects.get(name= form5.cleaned_data['prod_serv_name'])
                c.invoice_id = b.id
                c.prod_serv_id = nesto.id
                c.save()
                return HttpResponseRedirect('/izlazni_racuni/')
        else:
            form1 = InsertNewCustomer(prefix='form1')
            form2 = Outdrew(prefix='form2')
            form5 = MultiplyInsertValues(prefix='form5')

在此之后我收到错误消息: 无法分配“80”:“InvoiceProdService.invoice_id”必须是“OutgoingInvoice”实例。

问题在线:c.invoice_id = b.id

Django 版本:1.7.7

不知道这个问题出在哪里。

【问题讨论】:

    标签: python django forms orm


    【解决方案1】:

    它来自于您定义字段的方式。

    invoice_id = models.ForeignKey('OutgoingInvoice', related_name='outgoing_invoice', blank=True, null=True)
    

    Django 中的ForeignKey 增加了一些魔力,因此您可以直接处理对象。也就是说,根据您的定义,invoice_id 被假定为 OutgoingInvoice 的实际实例,而数字 id 实际上是 invoice_id_id

    您可能应该在模型中将 invoice_id 更改为 invoice

    invoice = models.ForeignKey('OutgoingInvoice', related_name='outgoing_invoice', blank=True, null=True)
    

    如果你这样做,Django 会自动将_id 附加到实际的数据库字段中,你可以通过 id 或通过对象访问它:

    c.invoice = b         # assign object
    c.invoice_id = b.id   # or assign id
    

    实际上这两行在 Django 中几乎是等价的。 您可以在relation fields 的文档中找到更多信息。

    【讨论】:

    • 感谢解决方案,@spectras
    猜你喜欢
    • 2016-01-06
    • 2021-01-10
    • 1970-01-01
    • 2010-12-28
    • 1970-01-01
    • 2019-04-15
    • 1970-01-01
    • 2017-11-20
    • 1970-01-01
    相关资源
    最近更新 更多