如何从django形式的外键中获取价值

时间:2014-02-01 13:22:08

标签: django python-2.7 django-models django-forms

大家好,我是新来的,现在我正在学习django。抱歉,如果我的问题不够准确,但我真的不知道怎么称呼它。这是我的代码:

库存/ models.py

class Category(models.Model):
    name = models.CharField(max_length=40)

class Product(models.Model):
    category = models.ForeignKey(Category)
    sale_price = models.DecimalField(max_digits=8, decimal_places=2, default=0.00)
    #...

发票/ models.py

from inventory.models import Product

class Invoice(models.Model):
    #...

class Row(models.Model):
    invoice = models.ForeignKey(Invoice)
    single_price = models.DecimalField(max_digits=8, decimal_places=2, default=0.00)
    #...

class InventoryRow(Row):
    product = models.ForeignKey(Product)
    def __unicode__(self):
        return self.product.name

发票/ forms.py

class InvoiceForm(ModelForm):
    class Meta:
        model = Invoice

class InventoryRowForm(ModelForm):
    class Meta:
        model = InventoryRow
        fields = ('product')

发票/ view.py

def invoice(request):
    TableFormSet = formset_factory(InventoryRowForm, extra=6)

    if request.method == 'POST':
        invoice_form = InvoiceForm(request.POST)
        table_formset = TableFormSet(request.POST)

        if invoice_form.is_valid() and table_formset.is_valid():
            invoice = invoice_form.save(commit=False)
            #...
            invoice.save()

            for form in table_formset.forms:
                t = form.save(commit=False)
                print t.product.sale_price
                t.single_price = t.product.sale_price
                t.invoice = invoice
                #...
                t.save()
            #From this place code doesn't execute

            return redirect('invoices:index')
    else:
        invoice_form = InvoiceForm()
        table_formset = TableFormSet()

    context = {
        'invoice_form': invoice_form,
        'table_formset': table_formset,
    }
    context.update(csrf(request))

    return render(request, 'invoices/invoice.html', context)

当我填写并发送表单时,我遇到了ExceptionType的HTTP错误500:DoesNotExist和ExceptionValue:InventoryRow没有产品。调试模式也突出显示我的行与作业“t.single_price = t.product.sale_price”我感到惊讶我可以打印t.product.sale_price的值到控制台,它是正确的,我的表格被保存。有谁知道为什么会这样?

Environment:

Request Method: POST
Request URL: http://192.168.0.104:8000/invoices/new/invoice

Django Version: 1.6.1
Python Version: 2.7.5
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'bootstrap_toolkit',
 'bootstrapform',
 'inventory',
 'invoices')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware')


Traceback:
File "/Users/novirael/PythonEnvs/BMSEnv/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  114.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/novirael/PythonEnvs/BMSEnv/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  22.                 return view_func(request, *args, **kwargs)
File "/Users/novirael/PythonEnvs/BMSEnv/bms/invoices/views.py" in invoice
  74.                 t.single_price = t.product.sale_price
File "/Users/novirael/PythonEnvs/BMSEnv/lib/python2.7/site-packages/django/db/models/fields/related.py" in __get__
  324.                 "%s has no %s." % (self.field.model.__name__, self.field.name))

Exception Type: DoesNotExist at /invoices/new/invoice
Exception Value: InventoryRow has no product.

1 个答案:

答案 0 :(得分:0)

您只需填写表单中的空表单。

在您看来:

TableFormSet = formset_factory(InventoryRowForm, extra=6)

每次点击此视图时,都会创建一个包含六个额外表单的表单集。然后,在for循环中,对form.save(commit=False)的调用不会返回带有关联InventoryRow对象的Product,因此当您稍后尝试时会出现DoesNotExist错误访问product.sale_price

您应该添加一个if来检查表单是否已“绑定”[1]:

for form in table_formset.forms:
    if form.is_bound:
        t = form.save(commit=False)
        t.single_price = t.product.sale_price
        t.invoice = invoice
        #...
        t.save()

[1]更多关于“约束形式”的信息:https://docs.djangoproject.com/en/dev/ref/forms/api/#bound-and-unbound-forms