Django模型表单和对象数据库id

时间:2010-09-06 21:14:02

标签: django django-models django-forms

我有一个复杂的django对象,它具有其他类类型的属性。这是这样的:

class Order:
   contractor - type Person
   some other fields....

在我的表单中,我希望能够从下拉列表中选择现有的Person对象,或者添加一个带有表单的新对象。我已经设法创建表单和适当的工作流程,但问题是保存Order本身,我根本无法获取已保存的Person实例的id。我正在做这样的事情:

def make_order(request):
  if request.method == 'POST':
    parameters = copy.copy(request.POST)
    contractor_form = ContractorForm(parameters)
    if contractor_form.is_valid():
      contractor_form.save()
      parameters['contractor'] = ???
    form = OrderForm(parameters)
    if form.is_valid():
      form.save() 
      return HttpResponseRedirect('/orders/')
  else:
    form = OrderForm()
    contractor_form = ContractorForm()

  return render_to_response('orders/make_order.html', {'order_form' : form, 'contractor_form' : contractor_form})

因此,如果POST请求到达此方法,我首先检查ContractorForm是否已被填充 - 我假设如果表单有效,则表示要使用它。如果是,则保存,并希望将保存对象的数据库ID分配给适当的字段,以便OrderForm找到它。

我的所有表单都是ModelForms。

问题是:

  1. 有更好的方法吗? (从下拉菜单中选择或添加到位) - 更好或更多pythonic; - )
  2. 如何在使用ModelForms时获取保存的对象ID?
  3. 被修改

    我的ContractorForm是:

    class ContractorForm(ModelForm):
      class Meta:
        model = Contractor
    

    没什么特别的。

1 个答案:

答案 0 :(得分:7)

save()应该返回新创建的实例。

if contractor_form.is_valid():
  instance = contractor_form.save()
  parameters['contractor'] = instance

其中id为instance.id,甚至更好instance.pk

pk vs. id

  

无论您是否定义了   主键字段自己,或者让   Django为您提供一个,每个型号   将有一个名为pk的属性。它   表现得像一个普通的属性   model,但实际上是别名   无论哪个属性是主键   模型的字段。你可以阅读和   设置这个值,就像你想的那样   任何其他属性,它会   更新模型中的正确字段。

对评论进行跟进:

默认情况下它确实有用,所以一定有其他错误。

<强> models.py

class Category(models.Model):
    name = models.CharField(max_length=70)
    slug = models.SlugField()

<强> forms.py

from django import forms
from models import Category

class MyModelForm(forms.ModelForm):
    class Meta:
        model = Category

在shell中测试:

In [3]: from katalog.forms import MyModelForm
In [4]: data = {'name':'Test', 'slug':'test'}
In [5]: form = MyModelForm(data)
In [6]: instance = form.save()
In [7]: instance
Out[7]: <Category: Test>
In [8]: instance.id
Out[8]: 5L