Передача значений во вложенные циклы for в django

#python #django

Вопрос:

Я зацикливаюсь между учебными пособиями и документацией по обратным отношениям. Я думаю, что моя проблема в том, что я не передаю правильную информацию из своего представления в шаблон, но я не уверен, как ее решить. Я хочу иметь возможность передавать все значения «подъема» из объекта LiftSets в их конкретный сеанс. Мой цикл for для сеансов (или total_workouts) работает, но я не могу получить ничего, для чего можно было бы заполнить вложенные.

 # views.py
def workout(request):
    total_workouts = Session.objects.all()
    total_sets1 = LiftSet.objects.all()

    context = {
        'total_workouts' : total_workouts,
        'total_sets1' : total_sets1,
    }


    return render(request, 'blog/workout.html', context=context)


# workout.html
    {% for workout in total_workouts %}
        <article class="media content-section">
          <div class="media-body">
            <div class="article-metadata">
              <a class="mr-2" href="#">{{ workout.author }}</a>
              <small class="text-muted">{{ workout.date_posted|date:"F d Y" }}</small>
            </div>
            <h2><a class="article-title" href="">{{ workout.name }}</a></h2>
            <p class="article-content">
                    test
                    {% for child in total_sets1.session_set.all %}
                        {{ child.lift }}
                    {% endfor %}
            </p>
          </div>
        </article>
    {% endfor %}
 

Внешний ключ в наборе ключей для привязки к сеансу.

 class Session(models.Model):
    name = models.CharField(max_length=100)
    date_posted = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

class LiftSet(models.Model):
    lift_options = (
        ('S', 'Squat'),
        ('B', 'Bench'),
        ('O', 'OHP'),
        ('R', 'Row'),
    )
    lift = models.CharField(
        max_length=1,
        choices=lift_options,
        blank=True,
        default='m',
        help_text='What Lift',
    )
    set = models.IntegerField()
    reps = models.IntegerField()
    weight = models.IntegerField()
    status_options = (
        ('P', 'Planned'),
        ('C', 'Completed'),
        ('F', 'Failed'),
        ('N', 'Not Attempted'),
    )
    status = models.CharField(
        max_length=1,
        choices=status_options,
        blank=True,
        default='P',
    )
    date_posted = models.DateTimeField(default=timezone.now)
    session = models.ForeignKey(Session, on_delete=models.CASCADE, null=True)  # don't actually want this as CASCADE

    def __str__(self):
        return self.lift
 

Ответ №1:

Я думаю, что, поскольку вы уже вызываете все объекты LiftSet модели total_sets1 = LiftSet.objects.all() и передаете их в качестве контекста, больше нет необходимости делать это в шаблоне:

  {% for child in total_sets1.session_set.all %}
     {{ child.lift }}
 {% endfor %}
 

Измените это на:

 {% for child in total_sets1 %}
    {{ child.lift }}
{% endfor %}
 

Кроме того, я мог бы изменить это views.py на:

 def workout(request, *args, **kwargs):
    total_workouts = Session.objects.all()
    total_sets1 = LiftSet.objects.all()

    context = {
        'total_workouts' : total_workouts,
        'total_sets1' : total_sets1,
    }


    return render(request, 'blog/workout.html', context)
 

Я надеюсь, что это поможет решить вашу проблему.

Редактировать:

На вашем views.py , если вы используете представления на основе классов, измените свою get функцию следующим образом:

 def get(self, request, sessionName):
        """GET method."""
        id = Session.objects.filter(name = sessionName).first()
        liftset = LiftSet.objects.filter(author= id)
        context = {
            "your_context": your_context 
        }
        return render(request, your_template.html , context)
 

Комментарии:

1. Спасибо. Это заставило работать цикл, но это вся база данных лифтов по сравнению с наборы подъемных, связанные с сеансом в верхнем цикле.

2. Никакой ошибки. Это дает мне: Сеанс 1, затем Набор лифтов1, Набор Лифтов2, Набор лифтов3; Сеанс 2, затем Набор Лифтов1, Набор Лифтов2, Набор Лифтов3. В отличие от сеанса 1 с его наборами подъемников и сеанса 2 с его наборами подъемников, такими как: Сеанс 1, затем набор подъемников1; Сеанс 2, затем набор подъемников 2 и 3.

3. Я отредактировал свой ответ, чтобы помочь решить эту проблему.