Django: несколько путей, один ListView, разные шаблоны?

#python #django

#python #django

Вопрос:

Пожалуйста, помогите мне. Я хочу иметь несколько путей в urls.py (допустим, a и b). Но я хочу иметь ТОЛЬКО один ListView, и этот ListView должен направлять меня в другой HTML-файл при доступе к URL (a.html при доступе к ‘a/’, b.html при доступе к ‘b/’).

В настоящее время я использую разные ListView для каждого пути (aListView и bListView), хотя модель одна и та же. Но, похоже, это нарушает правило «Не повторяйся». И код выглядит плохо.

Итак, вопрос в том, как я могу определить несколько разных шаблонов в одном ListView?

Ниже приведена моя текущая карта разума. Спасибо

Мой мысленный маршрут

Комментарии:

1. Если я правильно понял ваш вопрос, вы могли бы создавать материалы, связанные с БД, в models.py файл (имеющий класс и т.д.), Затем в views.py у вас может быть функция, которая дополнительно присваивает ей имя. Теперь в вашем приложении urls.py добавить 2 записи 1 предназначена для a.html и еще один для b.html с тем же именем функции, которое мы создали в views.py . таким образом, вы создали только 1 функцию, которая вызывается несколькими страницами (на основе их значений шаблона html). Пожалуйста, дайте мне знать, если это вам поможет, тогда это даст полный ответ.

Ответ №1:

Вот пример того, как вы можете определить несколько путей, которые указывают на один ListView в нескольких шаблонах:

Предположим, что имя моего приложения example и имя моего проекта test_project ; моя настройка такая:

test_project/urls.py

 from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    ...,  # my project urls
    path('', include('example.urls'))
]
  

example/urls.py

 from django.urls import path
from example import views

app_name = 'example'
urlpatterns = [
    path('a/', views.GenericListView.as_view(), name='a-url'),
    path('b/', views.GenericListView.as_view(), name='b-url')
]
  

templates/a.html

 This is A file
  

templates/b.html

 This is B file
  

example/views.py

 from django.views.generic.list import ListView
from django.urls import reverse


class GenericListView(ListView):
    a_template = 'a.html'
    b_template = 'b.html'

    def get_template_names(self, *args, **kwargs):
        # Check if the request path is the path for a-url in example app
        if self.request.path == reverse('example:a-url'):
            return [self.a_template]  # Return a list that contains "a.html" template name
        return [self.b_template]  # else return "b.html" template name

    def get_queryset(self, **kwargs):
        # For this example i'm returning [] as queryset for both a/ and b/ routes
        if self.request.path == reverse('example:a-url'):
            return []  # Return whatever queryset for a/ route
        return []  # Return whatever queryset for b/ route
  

Для получения дополнительной информации вы можете посетить документацию ListView: get_template_names()

Комментарии:

1. Это очень четкий ответ, и ссылка на документацию тоже полезна, я почти делал то же самое, но с HttpResponse в view.py за показ образца 🙂 опубликую, если смогу его завершить, приветствия и спасибо, что поделились хорошим ответом.

2. @RavinderSingh13 Спасибо. Смотрите Мое последнее обновление для более общего тестирования ваших URL-адресов. И не забудьте принять ответ, который отвечает на ваш вопрос.

3. @ChihebNexus отлично. Это то, что я ищу. Это помогает моему дню!! Спасибо!!

Ответ №2:

Мне кажется, что наличие 2 отдельных ListViews является правильным подходом в вашей ситуации. У вас есть 2 разных URL-адреса и 2 разных шаблона, поэтому у вас есть 2 разных представления. Я не думаю, что это нарушает принципы DRY, потому что общая логика абстрагируется многоразовым ListView классом.