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, но вышеуказанный тест проходит. Я не уверен, где именно я ошибся, поэтому любая помощь приветствуется.

Вы должны указать имя шаблонов в ListViews. По умолчанию 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/. Как только это было сделано, все заработало нормально.

Вернуться на верх