如何在表单完成期间设置外键(python/django)

Posted

技术标签:

【中文标题】如何在表单完成期间设置外键(python/django)【英文标题】:how to set foreign key during form completion (python/django) 【发布时间】:2012-02-16 19:13:18 【问题描述】:

在表单处理期间,我希望能够在模型对象上设置外键字段,而无需用户从下拉列表中选择键。

例如:

#models.py
class AAA(models.Model):

    some_field = models.TextField()

class BBB(models.Model):
    another_field = models.TextField()
    key_field = models.ForeignKey('AAA')

用户将从显示“AAA”实例的视图导航到 create_object 样式视图,该视图将在给定引用“AAA”的参数的情况下创建“BBB”实例。外键在代码中设置为指向“AAA”实例。

django cmets 框架似乎可以做到这一点,但我不知道怎么做。

有什么想法吗?我相信它应该很简单。

【问题讨论】:

【参考方案1】:

您可以从模型表单中排除key_field,使用commit=False 保存,然后在保存到数据库之前在视图中设置key_field

class BBBForm(forms.ModelForm):
    class Meta:
        model = BBB
        exclude = ("key_field",)

def create_view(request, **kwargs):
    if request.method == "POST":
        aaa = # get aaa from url, session or somewhere else
        form = BBBForm(request.POST)
        if form.is_valid():
            bbb = form.save(commit=False)
            bbb.key_field = aaa
            bbb.save()
            return HttpResponseRedirect("/success-url/")
        ...

【讨论】:

啊哈!我缺少的关键功能是“排除”声明。以前我的表单从未进入验证阶段,因为“key_field”是必填字段。非常感谢! @paulus_almighty 如果这篇文章解决了你的问题,你可以选择它作为你的接受(左边的绿色勾号),对于你所有的其他问题都是一样的【参考方案2】:

当用户通过AAA 的实例创建BBB 时,这应该反映在URL 中,即,您的“create_object 样式视图”将获得一个标识AAA 对象的参数。您可以使用它从数据库中获取对象并相应地创建您的 BBB 对象:

from django.shortcuts import get_object_or_404

def create_bbb_view(request, aaa_id):
    a = get_object_or_404(AAA, id=aaa_id)
    form = MyBBBCreationForm(request.POST) # or similar code
    if form.is_valid():
         b = BBB.objects.create(key_field=a) # plus other data from form
    # ...

(您也可以直接将key_field 设置为aaa_id,但最好检查对象是否存在。)

【讨论】:

以上是关于如何在表单完成期间设置外键(python/django)的主要内容,如果未能解决你的问题,请参考以下文章

最初在 django 内联表单集中设置不同的外键值

如何防止反序列化期间运行一段代码?

如何在 Django 表单中使用外键自动填充变量?

django:如何从包含外键的多个模型中制作一个表单

将外键放入表单

如何通过sqlyog对数据库表设置外键