Django Class Based View не удалось передать переменную в шаблон
Я новичок в Django и пытаюсь создать простой сайт-каталог. Я вставил некоторые данные в таблицу. Таким образом, в primary key = 1
Однако class
пуст после перехода к шаблону allclass_detail.html
. Над красной линией должен быть текст названия и описания, как на скриншоте Недостающий текст, но сейчас они отсутствуют
То же самое произошло и с AllClassDetailView()
, и с CombatEngravingDetailView()
views.py
from django.shortcuts import render
from .models import CombatEngraving, ClassEngraving, AllClass, Archetype
from django.views import generic
from django.shortcuts import HttpResponse, Http404
def index(request):
return render(request, 'index.html')
class AllClassListView(generic.ListView):
model = AllClass
paginate_by = 5
context_object_name = 'class_list'
template_name = 'catalog/class_list.html'
class AllClassDetailView(generic.DetailView):
model = AllClass
def all_class_detail_view(request, primary_key):
try:
the_class = AllClass.objects.get(pk=primary_key)
except AllClass.DoesNotExist:
raise Http404('Class does not exist')
return render(request, 'catalog/allclass_detail.html', context={'class': the_class})
class CombatEngravingListView(generic.ListView):
model = CombatEngraving
paginate_by = 10
context_object_name = 'combat_engraving_list'
template_name = 'catalog/combat-engraving.html'
class CombatEngravingDetailView(generic.DetailView):
model = CombatEngraving
def combat_engraving_detail_view(request, primary_key):
try:
combat_engraving = CombatEngraving.objects.get(pk=primary_key)
except CombatEngraving.DoesNotExist:
raise Http404('Combat Engraving does not exist')
return render(request, 'catalog/combatengraving_detail.html', context={'combat_engraving': combat_engraving})
class_list.html
{% extends "base_generic.html" %}
{% block content %}
<h1>Class List</h1>
{% if class_list %}
<ul>
{% for class in class_list %}
<li>
<a href="{{ class.get_absolute_url }}">{{ class.name }}</a>
 |{{class.archetype}}|
 {{class.first_class_engraving}} 
{{class.second_class_engraving}}
</li>
{% endfor %}
</ul>
{% else %}
<p>There are no class in Trixion.</p>
{% endif %}
{% endblock %}
allclass_detail.html
{% extends "base_generic.html" %}
{% block content %}
<h1>{{ class.name }}</h1>
<p><strong>Name:</strong> {{ class.name }}</p>
<p><strong>Archetype:</strong> {{ class.archetype }}</p>
<p><strong>First Class Engraving:</strong> {{ class.first_class_engraving }}</p>
<p><strong>Second Class Engraving:</strong> {{ class.second_class_engraving }}</p>
{% endblock %}
models.py
from django.urls import reverse
from django.db import models
from django.db.models import UniqueConstraint
from django.db.models.functions import Lower
class Archetype(models.Model):
name = models.CharField(max_length=40, unique=True,help_text="Name of this archetype(e.g. Martial Artist)")
class Meta:
ordering = ['name']
def get_absolute_url(self):
return reverse('archetype-detail', args=[str(self.id)])
def __str__(self):
return self.name
class AllClass(models.Model):
name = models.CharField(max_length=40, unique=True,help_text="Name of this class(e.g. Wardancer)")
archetype = models.ForeignKey('Archetype', on_delete=models.RESTRICT, null=True)
first_class_engraving = models.ForeignKey('ClassEngraving', on_delete=models.RESTRICT, null=True, related_name='first_eng')
second_class_engraving = models.ForeignKey('ClassEngraving', on_delete=models.RESTRICT, null=True, related_name='second_eng')
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('class-detail', args=[str(self.id)])
class Meta:
ordering = ['name']
constraints = [
UniqueConstraint(
Lower('name'),
name='genre_name_case_insensitive_unique',
violation_error_message="Class already exists (case insensitive match)"
),
]
class CombatEngraving(models.Model):
name = models.CharField(max_length=40, unique=True)
description = models.TextField(max_length=1000, unique=True)
class Meta:
ordering = ['name']
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('combat-engraving-detail', args=[str(self.id)])
class ClassEngraving(models.Model):
name = models.CharField(max_length=40, unique=True)
description = models.TextField(max_length=1000)
class Meta:
ordering = ['name']
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('class-engraving-detail', args=[str(self.id)])
Я попытался сделать the_class = AllClass.objects.get(pk=1)
вне метода. Он получил правильный результат, выведенный в терминал. Поэтому я думаю, что метод так и не был вызван? Но я не уверен, так как я делал другой подобный проект для начинающих, и он работал нормально.
Проблема заключается в том, как вы определили метод all_class_detail_view внутри класса. В представлениях Django, основанных на классах, такие методы, как get, post и т.д., вызываются автоматически в зависимости от метода HTTP-запроса, но дополнительные методы, такие как all_class_detail_view, не будут вызываться автоматически, если вы не вызовете их явно.
измените свой класс AllClassDetailView так, чтобы метод all_class_detail_view вызывался правильно:
class AllClassDetailView(generic.DetailView):
model = AllClass
def get(self, request, *args, **kwargs):
return self.all_class_detail_view(request, *args, **kwargs)
def all_class_detail_view(self, request, *args, **kwargs):
self.object = self.get_object()
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
также убедитесь, что ваши URL-адреса правильно настроены на использование вида AllClassDetailView