Общие виды Django: когда использовать ListView против DetailView

Я использую основанные на классах общие представления Django в приложении блога. Один из моих просмотров отображает список сообщений, которые имеют определенный тег. Я могу написать эту точку зрения как ListView сообщений, отфильтрованных по тегу. Или я могу написать эту точку зрения как DetailView тега и добавьте соответствующие сообщения в контекст.

Один способ более правильный - или Pythonic - чем другой?

ListView подход кажется более семантическим, потому что мне нужен список постов, но он также немного сложнее. Это требует, чтобы я переписал два метода. DetailView Подход требует только от меня перезаписать один метод.

class PostTagView(ListView):
    """Display all blog posts with a given tag."""
    queryset = Post.objects.published()

    def get_context_data(self, **kwargs):
        context = super(PostTagView, self).get_context_data(**kwargs)
        context['tag'] = get_object_or_404(Tag, slug=self.kwargs['slug'])
        return context

    def get_queryset(self, **kwargs):
        queryset = super(PostTagView, self).get_queryset()
        return queryset.filter(tags__slug=self.kwargs['slug'])


class TagDetailView(DetailView):
    """Display all blog posts with a given tag."""
    model = Tag

    def get_context_data(self, **kwargs):
        context = super(TagDetailView, self).get_context_data(**kwargs)
        context['object_list'] = Post.objects.published().filter(tags__slug=self.kwargs['slug'])
        return context

3 ответа

Решение

Как правило, посмотрите на параметры в URL. Если вы используете slug из Tag то вы, скорее всего, имеете дело с DetailView и не ListView,

В этом случае второй подход использует меньше кода, и он более элегантен. Однако это также зависит от того, что вы собираетесь делать с представлением позже. Если вы собираетесь добавить формы для редактирования сообщений, возможно, имеет смысл использовать ListView вместо. Но нет никакой технической причины, чтобы отдавать предпочтение одному над другим, просто вы можете в конечном итоге написать больше кода в одном подходе, чем в другом.

И ListView, и DetailView не являются технически одинаковыми. Например, вы не можете указать путь для DetailView, как показано ниже в urls.py,

path('schools_detail/',views.SchoolDetailView.as_view(),name = "detail"),

Это даст ошибку ниже,

Общий подробный вид SchoolDetailView должен вызываться с объектом pk или слагом в URLconf.

Это означает, что если у нас есть таблица с именем Student и другая таблица с именем School, мы можем использовать ListView для перечисления всех школ, как показано ниже,

path('list/',views.SchoolListView.as_view(),name = "list"),

И если мы хотим перечислить сведения о школах для отдельной школы, когда мы нажимаем значок школы, то мы можем использовать первичный ключ школы, который Django создает внутри, и записывать его в шаблон URL, в моем случае шаблон URL будет "list/{{school.id}}"поэтому, чтобы захватить это, мы должны дать путь, как показано ниже для DetailsView,

path('list/<int:pk>/',views.SchoolDetailView.as_view(),name = "detail"),

Таким образом, в итоге вы можете использовать ListView в качестве обычного представления для большинства случаев, если вы хотите получить доступ к другому представлению, но только к определенной детали в этом представлении, которое ссылается на первичный ключ, тогда вы можете использовать DetailsView (шаблон URL для DetailsView будет сгенерирован путем предоставления информации первичного ключа в URL, без первичного ключа в URL, он не будет работать, поскольку он не будет принимать всю информацию, вместо этого он будет принимать только информацию, относящуюся к первичному ключу в URL).

Интересный вопрос. К сожалению, ответ не так интересен: какой из них имеет наибольшее значение для вас и вашего приложения. Аргументы могут быть сделаны одинаково для любого подхода, так что на самом деле это просто суждение.

Вариант использования универсальных представлений на основе классов прекрасно описан в статье:

https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Generic_views

В вышеупомянутой статье вы сможете узнать, когда, почему и как использовать ListView/DetailView, а также простые примеры.

Другие вопросы по тегам