Django 将外键获取到窗体中

Django 将外键获取到窗体中,django,foreign-keys,modelform,django-forms,Django,Foreign Keys,Modelform,Django Forms,我是Django和Python新手,花了几天时间试图解决这个问题。我在其他线程中尝试过几种方法,但我认为我缺少一些基本概念,因为它们都不适合我。以下是我想做的: 我使用的是ModelForm,我创建了一个表单,用于添加包含外键的记录。我希望此值在默认情况下设置为与我链接的页面上显示的记录相匹配。[编辑下面显示的代码以显示建议的更正] 下面是views.py中的相关代码: def add_sighting(request): unit = request.GET.get('unit') form

我是Django和Python新手,花了几天时间试图解决这个问题。我在其他线程中尝试过几种方法,但我认为我缺少一些基本概念,因为它们都不适合我。以下是我想做的:

我使用的是ModelForm,我创建了一个表单,用于添加包含外键的记录。我希望此值在默认情况下设置为与我链接的页面上显示的记录相匹配。[编辑下面显示的代码以显示建议的更正]

下面是views.py中的相关代码:

def add_sighting(request):
unit = request.GET.get('unit')
form = SightingForm(request.POST or None, initial={'unit':unit})
if form.is_valid():
    sighting = form.save(commit=False)
    sighting.save()
    return redirect(index)
return render_to_response('trainapp/add_sighting_form.html',
                          {'unit': unit, 'sighting_form': form},
                          context_instance=RequestContext(request))
以下是add_sighting_form.html中的相关代码:

<form action="/trainapp/add_sighting/" method="post">
{% csrf_token %}
<table>
{{ sighting_form.as_table }}
</table>
<input type="submit" value="Save" />
</form>

{%csrf_令牌%}
{{sighting_form.as_table}
以下是我链接的模板中的相关代码:

<p><a href="/trainapp/add_sighting/?unit={{ unit.id }}">Add sighting</a></p>


这里可能有几种方法可以使用

最简单的方法是在将表单实例传递到某个视图的上下文之前,在创建表单实例时使用initial参数

假设您正在使用视图方法,如下所示:

def some_view( request ):
    id = request.GET.get( 'record-id' )
    # do check if id is valid...

    # load some record
    record = Record.objects.get( pk=id )

    # create a form instance
    form = RecordForm( initial={ 'some_key_field_name':record.id } )

    # set up context
    context = Context({
         'record' : record,
         'form' : form
    })

    # render the templateview using the above context
    # and return a HttpResponse ...
如果改用基于类的视图,则可能会覆盖get_context_数据以获得类似的结果

基于类的视图 基于您的代码,我还建议您看看Django中基于类的视图。 可以为您处理获取和发布表单。它甚至负责为您创建(默认)表单

发布代码的等价物如下所示:

class CreateSightingView( CreateView ):

    model = Sighting

    def get_context_data( self, **kwargs ):
        # call the super to get the default context
        data = super( CreateSightingView, self ).get_context_data( **kwargs )

        # add the initial value here
        # but first get the id from the request GET data
        id = self.request.GET.get( 'record-id' )
        # again: do some checking of id
        data.get( 'form' ).initial[ 'unit' ] = id

        return data

我不确定我是否已经将这个概念正确地应用到了我的代码中(我已经将它添加到了上面的问题中)。当我在表单上单击“保存”时,我得到以下错误:“IntegrityError at/trainapp/add_sighting/”,“trainapp_sighting.unit_id可能不为空”。错误具体发生在哪里?如果它在以下行:
form=SightingForm(request.POST或None,initial={'unit':unit.id})
那么我认为unit.id==null,这反过来表明unit的pk不是一个名为id的字段。是这样吗?我认为这会将主键的初始值设置为1,对吗?我想做的是将该值设置为与我链接的页面相匹配。好吧,你之前在帖子中展示的代码也有效地做到了这一点。您得到了一个pk=1的单元,然后将该id作为初始数据传递给表单。我刚刚向您展示了在表单中设置id的方法。我不能告诉你从哪里获得身份证,因为我不知道在哪里可以找到它。最简单的方法是将表单请求中的id作为GET变量传递。这样您就可以得到它,如上面编辑的代码所示。您还可以将其作为url kwarg传递;下面显示了url kwarg的示例。我感谢你在这方面的帮助。我将四处寻找有关如何将表单请求中的id作为GET变量传递的信息。我是否可以提供其他信息,帮助您完成这一步骤?