#django #templates #foreign-keys #many-to-many
#django #шаблоны #внешние ключи #многие ко многим
Вопрос:
Я новичок в django, и у меня довольно простой вопрос, однако я не смог найти свой ответ в Интернете, поэтому прошу прощения, если на этот вопрос был дан ответ ранее…
У меня есть 3 модели:
class Type(models.Model):
name = models.CharField(max_length=100)
class Exercise(models.Model):
name = models.CharField(max_length=100)
type = models.ForeignKey(Type, on_delete=models.CASCADE, default=1)
class Area(models.Model):
name = models.CharField(max_length=100)
notes = models.TextField(blank=True, null=True)
exercise = models.ManyToManyField(Exercise)
и 3 представления:
class AreaView(ListView):
model = Area
template_name = 'workouts/areas.html'
context_object_name = 'areas'
def get_context_data(self, **kwargs):
context = super(AreaView, self).get_context_data(**kwargs)
return context
class ExerciseView(ListView):
model = Area
template_name = 'workouts/exercises.html'
context_object_name = 'exercises'
def get_context_data(self, **kwargs):
context = super(ExerciseView, self).get_context_data(**kwargs)
return context
class TypeView(ListView):
model = Exercise
template_name = 'workouts/types.html'
context_object_name = 'types'
def get_context_data(self, **kwargs):
context = super(TypeView, self).get_context_data(**kwargs)
return context
Я зарегистрировал каждое представление на URL, подобный этому:
urlpatterns = [
path('', AreaView.as_view(), name='areas'),
path('exercises/<int:id>', ExerciseView.as_view(), name='exercises'),
path('types/<int:id>', TypeView.as_view(), name='types'),
]
и создал 3 шаблона, areas.html:
{% for area in areas %}
<ul>
<li><a href="{% url 'exercises' id=area.id %}">{{ area.name }}</a></li>
</ul>
{% endfor %}
exercises.html:
{% for area in areas %}
<ul>
<li><a href="{% url 'types' id=exercise.id %}">{% for exercise in area.exercise.all %}{{ exercise }}{% endfor %}</a></li>
</ul>
{% endfor %}
и types.html:
{% for exercise in exercises %}
<ul>
<li>{% for type in exercise.type.all %}{{ type}}{% endfor %}</li>
</ul>
{% endfor %}
Я добавил конкретные упражнения в каждую область в admin, а также конкретные типы для каждого упражнения. То, что я пытаюсь сделать, это отобразить полный список всех областей, в areas.html
которых затем ссылаются на список соответствующих им упражнений exercises.html
, которые, в свою очередь, затем ссылаются на страницу, на которой показаны соответствующие типы упражнений. Надеюсь, это имеет смысл… Я пробовал играть с различными соглашениями об именовании для контекста, циклов и тому подобного, но пока ничего не получилось так, как я хочу.
Нужно ли мне определять набор запросов в представлениях или есть что-то еще, что я делаю неправильно?
Ответ №1:
Для этого вы можете использовать DetailView.
class AreaDetailView(DetailView):
model = Area
context_object_name = 'area'
template_name = 'exercises.html'
И сопоставьте это подробное представление с URL-адресом следующим образом.
path('area/<int:pk>/detail/', AreaDetailView.as_view(), name='area_detail'),
Теперь вы можете связать этот URL-адрес в своем шаблоне.
{% for area in areas %}
<ul>
<li><a href="{% url 'area_detail' area.pk %}">{{ area.name }}</a></li>
</ul>
{% endfor %}
Теперь в exercise.html
вы можете получить соответствующее упражнение в этой области следующим образом.
{% for exercise in area.exercise_set.all %}
<ul>
<li><a href="{% url 'exercise_detail' id=exercise.id %}">{{ exercise.name }}</a></li>
</ul>
{% endfor %}
Аналогичным образом вы можете использовать аналогичный подход с ExerciseDetailView
Комментарии:
1. Большое вам спасибо за вашу помощь. Это почти сработало, мне просто нужно было изменить цикл for на
exercises.html
{% for exercise in area.exercise.all %}
, и это было идеально. Однако, используя ту же техникуtypes.html
, т. Е.{% for type in exercise.type.all %}
и{{ type.name }}
отображает только пустую страницу. Есть идеи, почему это так?2. это должно быть
{{exercise.type}}
только и удалить forloop, если вы хотите отобразить тип упражнения.3. Легенда. Теперь это идеально. Большое вам спасибо!