目前,我正处于Django的末尾,并希望添加一项功能来检查所使用的Question对象是否确实有任何选择。现在,它不会显示任何盒子并给我一个“投票”按钮,这实际上是无用的,因为我无法检查任何盒子。
我尝试使用'pk'关键字,当我进入网页时应该将其传递给DetailView,如下所示:
url(r'^specifics/(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
但是当我尝试在我的DetailView中使用pk变量时,它会抱怨它不知道pk名称下的任何关键字。我特别得到这个错误:NameError: name 'pk' is not defined
。在我的details.html中,我尝试打印出{{ question.pk }}
,这样做完美无缺(但我怀疑这是由于views.py中的投票功能)。
以下是我的网络应用中的DetailView和vote():
class DetailView(generic.DetailView):
question = get_object_or_404(Question, pk=pk)
model = Question
template_name = 'polls/detail.html'
question_exist = Question.objects.exists()
empty_choice = question[pk].choice_query.exists()
def get_queryset(self):
""" Exclude any unpublished questions. """
return Question.objects.filter(pub_date__lte=timezone.now())
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
except(KeyError, Choice.DoesNotExist):
# Redisplay the question voting form.
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice!",
})
else:
selected_choice.votes += 1
selected_choice.save()
# Always return HttpResonseRedirect after POST success, prevents
# data from being posted twice if someone hits the back button!
return HttpResponseRedirect( reverse('polls:results', args=(question.id, )) )
这是我的detail.html:
<h1> {{ question.question_text }} </h1>
{% if error_message %}<p> <strong> {{ error_message }} </strong> </p> {% endif %}
{% if empty_choice %}
<p> There are no choices! </p>
{% else %}
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}"
value="{{ choice.id }}"/>
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label>
<br />
{% endfor %}
<input type="submit" value="Vote" />
</form>
{% endif %}
{{ question.pk }}
question.pk在每个网站中返回正确的数字,但是当我尝试在DetailView中使用它时,Django说它不明白pk是什么。为什么呢?
答案 0 :(得分:2)
问题是您在定义班级时尝试访问pk
。
class DetailView(generic.DetailView):
question = get_object_or_404(Question, pk=pk)
由于您无法访问pk
,因此无法正常工作。处理请求时,您可以访问类方法中的pk
。
class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html'
def get_context_data(self, **kwargs):
context = super(DetailView, self).get_context_data(**kwargs)
context['empty_choice'] = self.object.choice_query.exists()
return context
def get_queryset(self):
""" Exclude any unpublished questions. """
return Question.objects.filter(pub_date__lte=timezone.now())
请注意,您不必使用get_object_or_404
来解决问题 - 通用视图的get_object
方法会为您解决此问题。
将您的观点命名为其他内容可能会更好(例如QuestionDetailView
,这样就不会与Django DetailView
混淆。
答案 1 :(得分:1)
在类构造期间不能使用pk
,在请求进入之前不会使用pk
。在可以采取任何请求之前将django加载到内存中时构造类。基本上你不能使用以下几行,因为当他们执行时,django对class DetailView(generic.DetailView):
question = get_object_or_404(Question, pk=pk)
question_exist = Question.objects.exists()
empty_choice = question[pk].choice_query.exists()
没有任何线索:
get_queryset
相反,您应使用pk
函数,该函数仅在请求进入时调用。self.kwargs
将在class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html'
def get_queryset(self):
""" Exclude any unpublished questions. """
return get_object_or_404( Question,
pk=self.kwargs['pk'],
pub_date__lte=timezone.now() )
中(因为您确实在其中为其命名) URLconf正则表达式:
^delete\(.*\)$
^ assert position at start of the string
delete matches the characters delete literally (case sensitive)
\( matches the character ( literally
.* matches any character (except newline)
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
\) matches the character ) literally
$ assert position at end of the string
(这个例子可能有一些怪癖,我还没有对它进行测试。为此道歉。我回家后会对它进行测试)