#python #django
#python #django
Вопрос:
Допустим, я хочу использовать LoginRequiredMixin и UserPermissionMixin, созданные мной, и применить их ко всем представлениям в приложении. Это всего лишь пример, у меня также могут быть mixins, которые добавляют некоторый контекст или делают другие вещи.
Я мог бы сделать это вручную, например, в этом представлении:
class MyCreateView(LoginRequiredMixin, UserPermissionMixin, CreateView)
Но, поскольку у меня много просмотров, и у меня могут быть другие конкретные mixins для некоторых представлений, это становится беспорядочным и сложным в управлении.
Одним из решений, которое пришло на ум, было бы создание новых классов для общих представлений:
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:
Ваш подход хорош. Я делал это для некоторых проектов с небольшой разницей:
myapp/views/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/views/base.py
from .generic import CreateView
class MyCreateView(CreateView):
pass
Он работает нормально, без особых проблем и позволяет вам легко пропустить mixin в исключительных случаях, если это необходимо.
Согласно usecase, другим решением может быть использование промежуточных программ или контекстных процессоров.
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
Комментарии:
1. Спасибо, я думаю, эта идея сэкономила мне 2 часа ручного редактирования всех существующих обновлений и CreateViews вместо изменения импорта!