2013-12-20 25 views
1

Добрый вечер. Я новичок в Django, и я играю с учебником по опросам. Я добавил новую модель «Секция», которая выступает в роли родителя для набора вопросов. Это отлично работает, поскольку в нем отображаются все вопросы раздела на странице html.объект не является итерируемым и/или 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 %} 

Но я получить

Exception Значение:
Объект «Вопрос» не является итерируемым

При удалении "на вопрос в latest_question_list" в detail.html я получить

Тип Exception: NoReverseMatch Exception Значение: R everse для 'голосования' с аргументами '(' '') и именованных аргументов '{}' не найдено. 1 образец (ы) попытался: [u'umfragen/(? P \ d +)/$ ']

Если я дополнительно удалю «{% url» опросы: vote' question.id%} "из действия формы, я Будем получать пустую форму. Я подозреваю, что передача данных отсутствует.

В чем может быть проблема?

Edit: 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_queryset в DetailView возвращается объект вопрос не запрос задавать. если вы измените return qs[0] на return qs, он вернет запрос, а не первый вопрос в этом списке.

Тип исключения: NoReverseMatch Значение исключения: R для «голосования» с аргументами '(' ',)' и аргументы ключевого слова '{}' не найдены. 1 модель (ы) пытались: [u'umfragen/(Р \ д +?)/$ ']

Теперь, когда петля удаляется, question не определен. вызов тега url не выполняется, потому что в нем отсутствует аргумент.

Макет пуст, поскольку он ссылается на значения в question, но question никогда не был установлен, потому что он был установлен в цикле.

Если вы хотите просто иметь дело с 1 вопрос, то снимите петлю и изменить context_object_name = 'latest_question_list' быть question, так это то, что ваш шаблон ссылки или рассмотреть подклассов DetailView вместо ListView и реализации get_object() вместо get_queryset()

+0

Спасибо за открытие. –

0

You используют ListView (даже если вы называете это DetailView :)), который построен для отображения списков объектов.

Первый шаг - фактически использовать the generic DetailView, который поставляется с Django, который построен для отображения отдельных объектов. Что-то вроде этого:

from django.views.generic import DetailView 

class YourView(DetailView): 
    model = Question 

Это автоматически присвоит Question, который соответствует слизняка в URL переменной шаблона question. Удалите {% for .. %} и {% endfor %} и {% if ... %}/{% endif %} пар из вашего шаблона и должен быть указан один вопрос.

+0

Спасибо за ответ. Я обязательно посмотрю на generic.DetailView –

+0

Slug - это раздел для набора вопросов, поэтому мне нужен цикл в DetailViews, чтобы получить следующий вопрос после того, как пользователь набрал save, правильно? –

+0

Было бы полезно, если бы вы смогли показать нам свои модели. – sk1p

Смежные вопросы