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

5 投票
2 回答
11801 浏览
提问于 2025-04-17 10:53

在处理表单的时候,我想要能够在一个模型对象上设置外键字段,而不需要用户从下拉菜单中选择这个键。

举个例子:

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

    some_field = models.TextField()

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

用户会从一个显示'AAA'实例的页面,跳转到一个创建'BBB'实例的页面,这个页面会根据一个指向'AAA'的参数来创建'BBB'。外键在代码中被设置为指向'AAA'的实例。

django的评论框架似乎是这样做的,但我搞不清楚具体怎么操作。

有没有什么想法?我觉得这应该很简单。

2 个回答

4

当用户通过一个AAA的实例创建一个BBB时,这个操作应该在网址上有所体现,也就是说,你的“创建对象的视图”会接收到一个参数,这个参数用来标识一个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,但最好还是先检查一下这个对象是否存在。)

31

你可以在你的模型表单中不包含 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/")
        ...

撰写回答