• How do I add a Foreign Key Field to a ModelForm in Django?


    What I would like to do is to display a single form that lets the user:

    • Enter a document title (from Document model)
    • Select one of their user_defined_code choices from a drop down list (populated by the UserDefinedCode model)
    • Type in a unique_code (stored in the Code model)

    I'm not sure how to go about displaying the fields for the foreign key relationships in a form. I know in a view you can use document.code_set (for example) to access the related objects for the current document object, but I'm not sure how to apply this to a ModelForm.

    My model:

    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)

    My ModelForm

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

    In regards to displaying a foreign key field in a form you can use the forms.ModelChoiceField and pass it a queryset.

    so, 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))

    from your question:

    I know in a view you can use document.code_set (for example) to access the related objects for the current document object, but I'm not sure how to apply this to a ModelForm.

    Actually, your Document objects wouldn't have a .code_set since the FK relationship is defined in your documents model. It is defining a many to one relationship to Code, which means there can be many Document objects per Code object, not the other way around. Your Code objects would have a .document_set. What you can do from the document object is access which Code it is related to using document.code.

    edit: I think this will do what you are looking for. (untested)

    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))

    actually you probably want to use get_or_create when creating your Code object instead of this.

    doc_code = Code(user_defined_code=user_defined_code, code=uniquecode)
  • 相关阅读:
    uboot nand erase 的显示错误修复
    Sougo for linux install.
    S3C6410移植uboot2010.3(2)基本的启动信息修改
    S3C6410移植uboot2010.3(4)uboot的dnw功能添加
    S3C6410移植uboot2010.3(3)正常化配置
    ubuntu乱码修复
    应老婆点(20070705 13:11:34)(新浪)
    克己慎独 2008923 13:32:00 (21ic)
    信任(20061229 14:16:32)(新浪)
    不要轻易承诺 2008926 14:42:00 (21ic)
  • 原文地址:https://www.cnblogs.com/floodwater/p/10023601.html
Copyright © 2020-2023  润新知