2011-04-18 63 views
18

我想什么做的是显示一个单一的形式,让用户:如何将外键字段添加到Django中的ModelForm中?

  • 输入文档标题(从Document模型)
  • 选择他们从下拉列表user_defined_code选择之一(人口稠密通过在unique_codeUserDefinedCode模型)
  • 类型(存储在Code模型)

我不知道如何去显示字段中脱颖而出在一个窗体中点击关键关系。我知道在视图中,您可以使用document.code_set(例如)访问当前document对象的相关对象,但我不知道如何将其应用于ModelForm。

我的模型:

class UserDefinedCode(models.Model): 
    name = models.CharField(max_length=8) 
    owner = models.ForeignKey(User) 

class Code(models.Model): 
    user_defined_code = models.ForeignKey(UserDefinedCode) 
    unique_code = models.CharField(max_length=15) 

class Document(models.Model): 
    title = models.CharField(blank=True, null=True, max_length=200) 
    code = models.ForeignKey(Code) 
    active = models.BooleanField(default=True) 

我的ModelForm

class DocumentForm(ModelForm): 
    class Meta: 
     model = Document 

回答

27

在问候的形式显示的外键字段,您可以使用forms.ModelChoiceField和它传递一个查询集。

所以,forms.py:

class DocumentForm(forms.ModelForm): 
    class Meta: 
     model = Document 

    def __init__(self, *args, **kwargs): 
     user = kwargs.pop('user','') 
     super(DocumentForm, self).__init__(*args, **kwargs) 
     self.fields['user_defined_code']=forms.ModelChoiceField(queryset=UserDefinedCode.objects.filter(owner=user)) 

views.py:

def someview(request): 
    if request.method=='post': 
     form=DocumentForm(request.POST, user=request.user) 
     if form.is_valid(): 
      selected_user_defined_code = form.cleaned_data.get('user_defined_code') 
      #do stuff here 
    else: 
     form=DocumentForm(user=request.user) 

    context = { 'form':form, } 

    return render_to_response('sometemplate.html', context, 
     context_instance=RequestContext(request)) 

从你的问题:

我知道在一个视图中,您可以使用 document.code_set (例如)到 访问 当前文档对象的相关对象,但是I当然不是 如何将其应用于ModelForm。

实际上,您的Document对象不会有.code_set,因为在您的文档模型中定义了FK关系。它正在定义与Code多对一的关系,这意味着每个对象可以有多个Document对象,而不是相反。你的Code对象将有一个.document_set。你可以从文档对象中做什么访问,它与使用document.code有关。

编辑:我认为这将做你正在寻找。 (未经测试)

forms.py:

class DocumentForm(forms.ModelForm): 
    class Meta: 
     model = Document 
     exclude = ('code',) 

    def __init__(self, *args, **kwargs): 
     user = kwargs.pop('user','') 
     super(DocumentForm, self).__init__(*args, **kwargs) 
     self.fields['user_defined_code']=forms.ModelChoiceField(queryset=UserDefinedCode.objects.filter(owner=user)) 
     self.fields['unique_code']=forms.CharField(max_length=15) 

views.py:

def someview(request): 
    if request.method=='post': 
     form=DocumentForm(request.POST, user=request.user) 
     if form.is_valid(): 
      uniquecode = form.cleaned_data.get('unique_code') 
      user_defined_code = form.cleaned_data.get('user_defined_code') 
      doc_code = Code(user_defined_code=user_defined_code, code=uniquecode) 
      doc_code.save() 
      doc = form.save(commit=False) 
      doc.code = doc_code 
      doc.save() 
      return HttpResponse('success') 
    else: 
     form=DocumentForm(user=request.user) 

    context = { 'form':form, } 

    return render_to_response('sometemplate.html', context, 
     context_instance=RequestContext(request)) 

实际上你可能要创建代码对象时,而不是该使用get_or_create。

doc_code = Code(user_defined_code=user_defined_code, code=uniquecode) 
+0

感谢您的帮助。我阅读了ModelChoiceField的文档,现在它很有意义。你知道我将如何在'unique_code'字段中显示CharField(我的问题中的第三个重点)吗?我已经略微减少了我的模型以使它们更易于阅读,但基本上我有一个分配有计算机生成的唯一文档代码的文档。每个用户都可以创建一个单独的用户代码,作为它们所拥有的所有文档的文档代码的前缀附加,因此是多个模型的原因。 – 2011-04-18 21:14:54

+0

@本S好吧,让我看看。我将编辑我的帖子。 – DTing 2011-04-18 21:17:17

+0

这很好。谢谢你的帮助。 – 2011-04-22 16:51:42

相关问题