Как мне применить Mixins ко всем CBV в приложении Django? - PullRequest
2 голосов
/ 19 апреля 2019

Допустим, я хочу использовать LoginRequiredMixin и UserPermissionMixin, созданные мной, и применить их ко всем представлениям в приложении. Это всего лишь пример, у меня также могут быть миксины, которые добавляют некоторый контекст или делают другие вещи.

Я мог бы сделать это вручную, например, это представление:

class MyCreateView(LoginRequiredMixin, UserPermissionMixin, CreateView)

Но, поскольку у меня много представлений, и у меня могут быть другие конкретные миксины для некоторых представлений, это становится грязным и сложным для управления.

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

class DecoratedCreateView(LoginRequiredMixin, UserPermissionMixin, CreateView):
    pass


class DecoratedDetailView(LoginRequiredMixin, UserPermissionMixin, DetailView):
    pass


class DecoratedUpdateView(LoginRequiredMixin, UserPermissionMixin, UpdateView):
    pass


class DecoratedDeleteView(LoginRequiredMixin, UserPermissionMixin, DeleteView):
    pass

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

class MyCreateView(DecoratedCreateView)

Это хороший подход? Нужно ли добавлять какие-либо методы в вышеприведенные классы или я просто оставляю их пустыми, и все будет работать как положено? Есть ли другой способ добиться этого, может быть, в urls.py?

1 Ответ

2 голосов
/ 19 апреля 2019

Ваш подход хорош. Я делал это для некоторых проектов с небольшой разницей:

MyApp / просмотров / generic.py

from django.views.generic import (
    CreateView as BaseCreateView,
    DetailView as BaseDetailView,
    UpdateView as BaseUpdateView,
    DeleteView as BaseDeleteView,
)

__all__ = ['MyappMixin', 'CreateView', 'DetailView', 'UpdateView', 'DeleteView']


class MyappMixin(LoginRequiredMixin, UserpermissionMixin):
    pass


class CreateView(MyappMixin, BaseCreateView):
    pass


class DetailView(MyappMixin, BaseDetailView):
    pass


class UpdateView(MyappMixin, BaseUpdateView):
    pass


class DeleteView(MyappMixin, BaseDeleteView):
    pass

MyApp / просмотров / base.py

from .generic import CreateView

class MyCreateView(CreateView):
    pass

Он работает отлично, без особых хлопот и позволяет легко пропустить миксин в исключительных случаях, если это необходимо.

В соответствии с вариантом использования, другим решением может быть использование middlewares или контекстных процессоров .

class MyMiddleware:

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        is_in_myapp = request.resolver_match.app_name == 'myapp'
        if is_in_myapp and not request.user.is_authenticated:
            response = HttpResponse("Permission denied", status=403)
        else:
            response = self.get_response(request)
        return response
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...