#python #django #decorator
Вопрос:
Я создал два декоратора, чтобы заблокировать любому доступ к определенному контенту, например:
@method_decorator(login_required(login_url='core:login'), name='dispatch')
@method_decorator(allowed_users(allowed_roles=['writer']), name='dispatch')
class BookDeleteView(BSModalDeleteView):
model = Book
template_name = 'book/book_delete.html'
success_message = 'Success: book was deleted.'
success_url = reverse_lazy('core:book_list')
я хочу создать декоратора, который выглядит так
book=Book.objects.get(id=pk)
if request.user==book.writer.profile.user:
Ответ №1:
Если вы хотите использовать декоратора:
def writers_only(function):
@wraps(function)
def wrap(request, *args, **kwargs):
if request.user == Book.objects.get(id=kwargs.get('pk')).writer.profile.user:
return function(request, *args, **kwargs)
else:
# Do something else
return wrap
Затем добавьте это в представление на основе классов:
# Other decorators
@method_decorator(writers_only, name='dispatch')
class BookDeleteView(BSModalDeleteView):
# Your code
В противном случае вы также можете переопределить BookDeleteView.get_object
(вы можете создать микс для повторного использования этой реализации get_object
в различных представлениях):
@method_decorator(login_required(login_url='core:login'), name='dispatch')
@method_decorator(allowed_users(allowed_roles=['writer']), name='dispatch')
class BookDeleteView(BSModalDeleteView):
model = Book
template_name = 'book/book_delete.html'
success_message = 'Success: book was deleted.'
success_url = reverse_lazy('core:book_list')
def get_object(self, *args, **kwargs):
obj = super().get_object(*args, **kwargs)
if obj.writer.profile.user != self.request.user:
raise PermissionDenied() # Or do something else
return obj
Ответ №2:
Для этого вам не нужен декоратор. То, что вам нужно queryset
, определено в вашем представлении модели, которое будет ограничивать запрос:
class BookDeleteView(BSModalDeleteView):
def get_queryset(self):
return self.model.objects.filter(user=self.request.user)
В случае, если это необходимо сделать только для удаления, вы также можете установить его динамически в зависимости от запроса:
class BookDeleteView(BSModalDeleteView):
def get_queryset(self):
if self.request.method == 'DELETE':
return self.model.objects.filter(user=self.request.user)
return self.model.objects.all()