2013-12-20 54 views
1

晚上好。我是Django的新手,我在玩民意调查教程。我添加了一个新的模型“部分”,作为一组问题的父母。这是工作正常,因为它显示了一个页面上的一节的所有问题。对象不可迭代和/或NoReverseMatch

我现在要做的是每页仅显示一个问题,将答案保存到数据库并从该部分获取下一个问题。我尝试了几种不同的方式,但没有任何效果。我希望你们能引导我走向正确的方向。

URLS.PY 
urlpatterns = patterns('', 
    url(
     regex=r'^$', 
     view=UmfrageView.as_view(), 
     name='umfrage' 
    ), 
    url(
     regex=r'^(?P<slug>[-\w]+)/$', 
     view=DetailView.as_view(), 
     name='detail' 
    ), 
    url(
     regex=r'^(?P<question_id>\d+)/$', 
     view=vote, 
     name='vote' 
    ), 
) 

试图从一节的第一个问题:

VIEWS.PY 
class DetailView(ListView): 
    model = Question 
    context_object_name = 'latest_question_list' 
    template_name = 'itbarometer/detail.html' 

    def get_queryset(self, **kwargs): 
     # Get question set via section slug 
     slug = self.kwargs.get('slug') or kwargs.get('slug') 
     qs = Question.objects.filter(section__slug=slug).order_by('pub_date') 
     try: 
      return qs[0] 
     except IndexError: 
      return None 

def vote(request, question_id): 
    p = get_object_or_404(Question, pk=question_id) 
    try: 
     selected_choice = p.choice_set.get(pk=request.POST['choice']) 
    except (KeyError, Choice.DoesNotExist): 
     # Redisplay the question voting form 
     return render(request, 'itbarometer/umfrage.html', { 
      'question': p, 
      'error_message': "Bitte eine Antwort auswählen.",}) 
    else: 
     selected_choice.votes += 1 
     selected_choice.save() 
     return HttpResponseRedirect(reverse('polls:umfrage')) 

HTML模板detail.html:

{% if latest_question_list %} 
    {% for question in latest_question_list %} 
     <form action="{% url 'polls:vote' question.id %}" method="post"> 
      <fieldset> 
       <legend>{{ question.question_text }}</legend> 
       {% 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 %} 
      </fieldset> 
      <input class="button small" type="submit" value="Save" /> 
     </form> 
    {% endfor %} 
{% endif %} 

但我会得到

异常值:
'问题'对象不可迭代

当detail.html删除“在latest_question_list问题:”我会得到

异常类型:NoReverseMatch 异常值: [R EVERSE为“投票”与参数“(”“)”和关键字参数'{}' 未找到。尝试1个模式:[u'umfragen /(?P \ d +)/ $']

如果我从表单操作中进一步删除“{%url”polls:vote'question.id%}“将会得到一个空的表单布局。我怀疑没有数据传输。

可能是什么问题?

编辑:models.py

class Section(models.Model): 
    section_text = models.CharField(max_length=255) 
    section_description = models.TextField(blank=False) 
    slug = models.SlugField(unique=True, null=True) 

    def __unicode__(self): 
     return self.section_text 

    def save(self, *args, **kwargs): 
     self.slug = slugify(self.section_text) 
     super(Section, self).save(*args, **kwargs) 


class Question(models.Model): 
    section = models.ForeignKey(Section) 
    question_text = models.CharField(max_length=200) 
    pub_date = models.DateTimeField('date published') 

    def __unicode__(self): 
     return self.question_text 

    def was_published_recently(self): 
     now = timezone.now() 
     return now - datetime.timedelta(days=1) <= self.pub_date < now 

    was_published_recently.admin_order_field = 'pub_date' 
    was_published_recently.boolean = True 
    was_published_recently.short_description = 'Published recently?' 


class Choice(models.Model): 
    question = models.ForeignKey(Question) 
    choice_text = models.CharField(max_length=200) 
    votes = models.IntegerField(default=0) 

回答

0

异常值: '问题' 对象不是可迭代

你得到这一点,因为在get_querysetDetailView返回一个问题对象不是一个查询组。如果您将return qs[0]更改为return qs它将返回一个查询集而不是该列表中的第一个问题。

异常类型:NoReverseMatch异常值:对'vote'进行反转,未找到参数'('',)'和关键字参数'{}'。 1个图案(多个)尝试:[u'umfragen /(P \ d +?)/ $']

既然环路解除,question没有定义。对url标记的调用失败,因为它现在缺少一个参数。

布局为空,因为它引用了question中的值,但question从未设置,因为在循环中设置了该值。

如果你想只用1个问题处理然后取出循环和改变context_object_name = 'latest_question_list'question,因为这是你的模板被引用或者考虑继承DetailView代替ListView和实施get_object()代替get_queryset()

+0

感谢您的大开眼界。 –

0

您的正在使用一个ListView(即使你称之为DetailView :)),这是建立显示对象列表。

第一步是实际使用Django附带的the generic DetailView,它是为了显示单个对象而构建的。事情是这样的:

from django.views.generic import DetailView 

class YourView(DetailView): 
    model = Question 

这将自动分配中的URL模板变量question蛞蝓匹配的Question。从您的模板中删除{% for .. %}{% endfor %}{% if ... %}/{% endif %}对,应显示单个问题。

+0

感谢您的回答。我肯定会研究generic.DetailView –

+0

slug是一组问题的一部分,所以我需要在DetailViews中的循环来获取用户点击保存后的下一个问题,对吧? –

+0

如果您能向我们展示您的模型,将有所帮助 – sk1p