为 Django 模型自动填充外键

Posted

技术标签:

【中文标题】为 Django 模型自动填充外键【英文标题】:Auto fill ForeignKey for Django Model 【发布时间】:2012-10-21 18:10:00 【问题描述】:

所以我正在构建一个基本的问答网站——每个主题都有一系列与之相关的问题,每个问题都有与之相关的多个答案。

我正在为问题创建用户输入,它们必须与某个主题相关联。这是问题模型

#models.py
class Question(models.Model):
    movie           = models.ForeignKey(Movie, blank=True, null=True)
    question_text   = models.CharField(max_length = 1000)
    question_detail = models.CharField(max_length = 5000, blank = True, null = True)
    q_pub_date      = models.DateTimeField(auto_now_add = True)
    q_author        = models.ForeignKey(User)
class QuestionForm(ModelForm):
    def save(self, user = None, force_insert = False, force_update = False, commit = True):
        q = super(QuestionForm, self).save(commit = False)
        q.q_author = user
        if commit:
            q.save()
        return q

    class Meta:
        model = Question
        exclude = ('movie', 'q_author', 'q_pub_date')

这是网址配置

#urls.py
url(r'^(?P<movie_id>\d+)/add_question/$', 'add_question'),

现在是视图

#views.py
def add_question(request, movie_id):
    if request.method == "POST":
        form = QuestionForm(request.POST, request.FILES)
        #QuestionForm.movie = Movie.objects.get(pk = movie_id)
        if form.is_valid():
            form.save(user = request.user)
            return HttpResponseRedirect("/home/")
    else:
        form = QuestionForm()
    return render_to_response("qanda/add_question.html", 'form': form, context_instance = RequestContext(request))

这是 HTML 代码

#add_question.html
<h1> Add Question:  user.username </h1>
    <form action = "" method = "post">% csrf_token %
         form.as_p 
        <input type = "submit" value = "Ask" />
        <input type = "hidden" name = "next" value = " next|escape " />
    </form>

在视图中,注释掉的行是我添加到视图中以尝试自动保存模型的内容。添加问题时,URL 具有与其关联的电影的 ID,我的想法是获取该 ID,然后将其插入 ForeignKey 以识别与问题关联的电影。但是,当我使用我的代码时,它会将所有问题的电影关联更改为当前电影,而不仅仅是更改特定问题的电影关联。没有代码,它根本不会将电影与问题相关联。我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

使用这个:

#views.py
def add_question(request, movie_id):
    if request.method == "POST":
        form = QuestionForm(request.POST, request.FILES)
        if form.is_valid():
            question = form.save(user = request.user)
            question.movie = Movie.objects.get(pk = movie_id)
            question.save()
            return HttpResponseRedirect("/home/")
    else:
        form = QuestionForm()
    return render_to_response("qanda/add_question.html", 'form': form, context_instance = RequestContext(request)

评论中提出的问题

您应该避免在视图或模板中使用绝对 URL。考虑一个场景,您决定将home URL 从/home/ 更改为/myhome/。您必须在曾经使用过它们的地方对其进行编辑。命名网址总是更好的(docs):

# URL Conf
url(r'^home/$', 'home_view', name="home_url"),
url(r'^(?P<movie_id>\d+)/add_question/$', 'add_question', name="add_question_url"),
url(r'^home/(?P<movie_id>\d+)/$', 'movie_view', name="movie_url"),

name 参数充当您实际 URL 的唯一标识符

现在在你看来:

from django.core.urlresolvers import reverse

def some_view(request):
    ...
    return HttpResponseRedirect(reverse('home_url'))

现在,您对 URL 所做的任何更改(比如 /home/ 到 /myhome/ 对视图都没有影响,只要 name 参数在 URL conf 中具有相同的值。

如果你想传递参数(比如你的电影 ID)

def some_view(request, movie_id):
    ...
    return HttpResponseRedirect(reverse('movie_url', kwargs='movie_id':movie_id))

应在模板中使用相同的概念,以避免在模板中硬编码 URL。请阅读this了解更多详情

【讨论】:

太棒了。完美地工作。多谢!还有一个——如何将用户重定向回上一个 URL?我可以将变量放入 HttpResponseRedirect("home/(?P\d+)/) 还是有更好的方法? 您应该避免在视图中使用绝对 URL。我正在编辑答案以显示我应该如何完成

以上是关于为 Django 模型自动填充外键的主要内容,如果未能解决你的问题,请参考以下文章

Django 应用程序:必须将图像上传到的目录名称,应自动填充

为啥 PyCharm 不建议为 django 模型自动填充?

Django Rest Framework:POST时自动填充模型的字段?

如何在 Django 中从用户模型的字段自动填充和显示数据到来自不同应用程序的另一个模型?

如何根据 M2M 关系在 django 模型中自动填充 IntegerField?

外键未填充主键值