Django & rest_framework – метод get_queryset вызывается дважды, есть ли другое лучшее решение?Python

Программы на Python
Anonymous
Django & rest_framework – метод get_queryset вызывается дважды, есть ли другое лучшее решение?

Сообщение Anonymous »

В настоящее время у меня есть проект, использующий django и rest_framework для запуска некоторых базовых API.
Проблема в том, что когда я создаю представление, используя общую библиотеку для rest_framework и DjangoModelPermissions, мой метод get_queryset вызывается дважды
Мой класс разрешений

Код: Выделить всё

class DefaultModelPermissions(DjangoModelPermissions):
"""
The request is authenticated using `django.contrib.auth` permissions.
See: https://docs.djangoproject.com/en/dev/topics/auth/#permissions

It ensures that the user is authenticated, and has the appropriate
`view`/`add`/`change`/`delete` permissions on the model.

This permission can only be applied against view classes that
provide a `.queryset` attribute.
"""
perms_map = {
'GET': ['%(app_label)s.view_%(model_name)s'],
'OPTIONS': ['%(app_label)s.view_%(model_name)s'],
'HEAD': ['%(app_label)s.view_%(model_name)s'],
'POST': ['%(app_label)s.add_%(model_name)s'],
'PUT': ['%(app_label)s.change_%(model_name)s'],
'PATCH': ['%(app_label)s.change_%(model_name)s'],
'DELETE': ['%(app_label)s.delete_%(model_name)s'],
}

class DefaultModelViewPermissions:
permission_classes = (DefaultModelPermissions,)
Мое мнение

Код: Выделить всё

class AgentListCreateView(DefaultModelViewPermissions, generics.ListCreateAPIView):
serializer_class = serializers.AgentSerializer

def get_queryset(self):
print('get_queryset')
return models.Agent.objects.all()
При отладке приложения я обнаружил, что разрешение также вызывает get_queryset для получения модели и проверки разрешений пользователя django.
permission_calling_get_queryset
p>
С моей точки зрения, это ненужная операция. В зависимости от размера таблицы БД это может стать серьезной проблемой производительности и привести к множеству других проблем с приложениями.
Моим решением было переопределить этот метод has_permission. Итак, мой класс стал похож

Код: Выделить всё

class DefaultModelPermissions(DjangoModelPermissions):
"""
The request is authenticated using `django.contrib.auth` permissions.
See: https://docs.djangoproject.com/en/dev/topics/auth/#permissions

It ensures that the user is authenticated, and has the appropriate
`view`/`add`/`change`/`delete` permissions on the model.

This permission can only be applied against view classes that
provide a `.queryset` attribute.
"""
perms_map = {
'GET': ['%(app_label)s.view_%(model_name)s'],
'OPTIONS': ['%(app_label)s.view_%(model_name)s'],
'HEAD': ['%(app_label)s.view_%(model_name)s'],
'POST': ['%(app_label)s.add_%(model_name)s'],
'PUT': ['%(app_label)s.change_%(model_name)s'],
'PATCH': ['%(app_label)s.change_%(model_name)s'],
'DELETE': ['%(app_label)s.delete_%(model_name)s'],
}

def has_permission(self, request, view):
if not request.user or (
not request.user.is_authenticated and self.authenticated_users_only):
return False

# Workaround to ensure DjangoModelPermissions are not applied
# to the root view when using DefaultRouter.
if getattr(view, '_ignore_model_permissions', False):
return True

# Workaround cause base class utilized get_queryset to retrieve the model
# making unecessary requisitions to the database
if hasattr(view, 'get_serializer_class'):
model = view.get_serializer_class().Meta.model
else:
model = view.serializer_class.Meta.model

perms = self.get_required_permissions(request.method, model)

return request.user.has_perms(perms)
Мой вопрос:
Есть ли лучший способ обойти это? Есть ли у кого-нибудь еще такая же проблема?

Подробнее здесь: https://stackoverflow.com/questions/788 ... here-any-o

Вернуться в «Python»