【问题标题】:object is not iterable and/or NoReverseMatch对象不可迭代和/或 NoReverseMatch
【发布时间】:2014-01-09 16:23:12
【问题描述】:

晚上好。我是 Django 的新手,我正在玩民意调查教程。我添加了一个新模型“Section”,它充当一组问题的父级。这很好用,因为它显示了 html 页面上某个部分的所有问题。

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

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中删除“for question in latest_question_list”时,我会得到

异常类型:NoReverseMatch 异常值: 未找到带有参数 '('',)' 和关键字参数 '{}' 的“投票”。尝试了 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)

【问题讨论】:

    标签: django django-views


    【解决方案1】:

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

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

    异常类型:NoReverseMatch 异常值:未找到带有参数“(”,)”和关键字参数“{}”的“投票”。尝试了 1 种模式:[u'umfragen/(?P\d+)/$']

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

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

    如果您确实只想处理 1 个问题,请删除循环并将 context_object_name = 'latest_question_list' 更改为 question,因为这是您的模板所引用的或考虑子类化 DetailView 而不是 ListView 并实现 @987654333 @而不是get_queryset()

    【讨论】:

    • 感谢您的大开眼界。
    【解决方案2】:

    您正在使用ListView(即使您称其为DetailView :)),它是为显示对象列表而构建的。

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

    from django.views.generic import DetailView
    
    class YourView(DetailView):
        model = Question
    

    这将自动将与 url 中的 slug 匹配的 Question 分配给模板变量 question。从模板中删除 {% for .. %}{% endfor %}{% if ... %} / {% endif %} 对,应该会显示单个问题。

    【讨论】:

    • 感谢您的回答。我一定会研究 generic.DetailView
    • slug 是一组问题的部分,所以我需要在 DetailViews 中循环以在用户点击保存后获取下一个问题,对吧?
    • models.py 已添加到问题中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-18
    • 2021-11-14
    • 2019-11-12
    • 2017-01-05
    • 2015-11-11
    • 2021-06-06
    相关资源
    最近更新 更多