首页 > 解决方案 > Django displays incorrect template

问题描述

I'm working on an website where user (if logged in) can perform a calculation and see all of his calculations listed. My website has two groups: Clients and Administrators where Clients are not allowed to see any other members' calculations except their own while Administrators are. Authentication is based on Django's built in User class and for each group I created separate views and templates. Templates have similar behavior but different displaying messages. When Clients want to see their calculations, correct information is displayed but the template rendered is for Administrators rather than for Clients.

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'),
]

Template names

Administrators: calculation_list.html
Clients: calculations_user.html

EDIT: I mistakenly posted wrong test function. So, here's the one that produced the output referenced few lines below.

test.py

def test_logged_in_uses_correct_template(self):
        login = self.client.login(username='testuser1', password='1X<ISRUkw+tuK')
        response = self.client.get(reverse('mycalcs'))

        # Check if user is logged in
        self.assertEqual(str(response.context['user']), 'testuser1')
        # Check for the response "success"
        self.assertEqual(response.status_code, 200)

        # Check if correct template used
        self.assertTemplateUsed(response,'cycle/calculations_user.html')

Test response

======================================================================
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

I tried changing mappings and names of the urls but than I get NoReverseMatch error when I run server but the above test passes. I'm not sure where exactly did I mess up so any help is welcome.

标签: pythondjango

解决方案


You should specify the name of the templates in the ListViews. By default a ListView [Django-doc] will use the name of the model (here calculation), and then add a suffix _list to it, this thus means that a ListView with Calculation as model, will render the calculation_list.html template.

But this makes no sense for the CalculationsByUserListView, you thus should specify the template_name [Django-doc] with:

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)

推荐阅读