Django отображает неправильный шаблон
Я работаю над сайтом, где пользователь (если он вошел в систему) может выполнить расчет и увидеть все свои расчеты в списке. На моем сайте есть две группы: Клиенты и Администраторы, где Клиентам не разрешается видеть расчеты других пользователей, кроме своих собственных, а Администраторам разрешается. Аутентификация основана на встроенном в Django классе User, и для каждой группы я создал отдельные представления и шаблоны. Шаблоны имеют схожее поведение, но разные отображаемые сообщения. Когда клиенты хотят увидеть свои расчеты, отображается правильная информация, но шаблон отображается для администраторов, а не для клиентов.
views.py
#Administrators' view function
class CalculationListView(generic.ListView):
model = Calculation
paginate_by = 10
#Users' view function
class CalculationsByUserListView(LoginRequiredMixin, generic.ListView):
model = Calculation
paginate_by = 10
def get_queryset(self):
return Calculation.objects.filter(userid=self.request.user)
urls.py
urlpatterns = [
path('', views.index, name='index'),
path('calculations/', views.CalculationListView.as_view(), name='calculations'),
path('calculation/<int:pk>', views.CalculationDetailView.as_view(), name='calculation-detail'),
]
urlpatterns += [
path('mycalculation/', views.CalculationsByUserListView.as_view(), name='mycalcs'),
]
Имена шаблонов
Administrators: calculation_list.html
Clients: calculations_user.html
test.py
def test_calculations_in_list(self):
login = self.client.login(username='testuser1', password='1X<ISRUkw+tuK')
response = self.client.get(reverse('mycalcs'))
# Check our user is logged in
self.assertEqual(str(response.context['user']), 'testuser1')
# Check that we got a response "success"
self.assertEqual(response.status_code, 200)
# Check that initially we don't have any calculations in list
self.assertTrue('calculation_list' in response.context)
self.assertEqual(len(response.context['calculation_list']), 0)
# Now assign some calculations to testuser1
calculation = Calculation.objects.all()[:10]
for calc in calculation:
User.username = 'testuser1'
calc.save()
# Check that now we have some calculations in the list
response = self.client.get(reverse('mycalcs'))
# Check our user is logged in
self.assertEqual(str(response.context['user']), 'testuser1')
# Check that we got a response "success"
self.assertEqual(response.status_code, 200)
self.assertTrue('calculation_list' in response.context)
# Confirm all calculations belong to testuser1
for calc in response.context['calculation_list']:
self.assertEqual(response.context['user'], calc.userid)
Тестовый ответ
======================================================================
FAIL: test_logged_in_uses_correct_template (cycle.tests.test_views.CalculationsByUserListViewTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\DEBIEVEL\Desktop\Work\Edited\django_test\orc2\cycle\tests\test_views.py", line 80, in test_logged_in_uses_correct_template
self.assertTemplateUsed(response, 'cycle/calculations_user.html')
File "C:\ProgramData\Anaconda3\lib\site-packages\django\test\testcases.py", line 661, in assertTemplateUsed
% (template_name, ', '.join(template_names))
AssertionError: False is not true : Template 'cycle/calculations_user.html' was not a template used to render the response. Actual template(s) used: cycle/calculation_list.html, base_generic.html
Я пробовал менять маппинг и имена урлов, но при запуске сервера я получаю ошибку NoReverseMatch, но вышеуказанный тест проходит. Я не уверен, где именно я ошибся, поэтому любая помощь приветствуется.
Вы должны указать имя шаблонов в ListView
s. По умолчанию ListView
[Django-doc] будет использовать имя модели (здесь calculation
), а затем добавлять к нему суффикс _list
, это означает, что ListView
с Calculation
в качестве модели будет отображать шаблон calculation_list.html
.
Но это не имеет смысла для CalculationsByUserListView
, поэтому вы должны указать template_name
[Django-doc] с:
class CalculationsByUserListView(LoginRequiredMixin, generic.ListView):
model = Calculation
paginate_by = 10
template_name = 'calculations_user.html'
def get_queryset(self):
return Calculation.objects.filter(userid=self.request.user)
Итак, проблема была не в определении представления, а в шаблоне. Как только я применил решение @Willem Van Onsem, я начал получать ошибку NoReverseMatch для части моего шаблона, которая фактически отображает список. При дальнейшем рассмотрении я обнаружил, что именно цикл for в шаблоне вызвал ошибку. Поскольку я не публиковал код шаблона раньше, мы не смогли заметить это раньше.
Старый цикл for:
<ul>
{% for calc in calculation_list %}
<li> <a href="{% url 'calculation-detail' calc.user.pk %}"> Performed on {{calc.time_calculated}}</a>
</li>
{% endfor %}
</ul>
Новый цикл for:
<ul>
{% for calc in calculation_list %}
<li> <a href="{{ calc.get_absolute_url }}"> Performed on {{calc.time_calculated}}</a>
</li>
{% endfor %}
</ul>
Мне также нужно было переместить этот конкретный шаблон из папки templates/cycle в папку templates/. Как только это было сделано, все заработало нормально.