为Django Model自动填充ForeignKey

时间:2012-11-01 06:49:46

标签: python html django django-models views

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

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

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

这是URL conf

#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 个答案:

答案 0 :(得分:2)

使用此:

#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网址从/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参数作为实际网址的唯一标识符

现在在你的观点中:

from django.core.urlresolvers import reverse

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

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

如果你想传递参数(比如你的情况下的movie_id)

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

模板中应使用相同的概念,以避免在模板中对URL进行硬编码。有关详细信息,请阅读this