Я продолжаю свой путь тестирования моего приложения Django Rest Framework, так как я добавляю новые представления и дополнительные функциональные возможности. Я должен признать, что на данном этапе я считаю, что тестирование сложнее, чем собственно кодирование и сборка моего приложения. Я чувствую, что ресурсов для тестирования DRF гораздо меньше, чем ресурсов, рассказывающих о создании инфраструктуры REST с DRF. C'est la vie, однако, я воюю.
Моя проблема, с которой я сейчас сталкиваюсь, заключается в том, что я получаю ошибку 403 при тестировании одного из моих DRF ViewSets. Я могу подтвердить, что представление и его разрешения работают нормально при использовании браузера или обычного сценария Python для доступа к конечной точке.
Давайте начнем с модели, которая используется в моем ViewSet
class QuizTracking(models.Model):
case_attempt = models.ForeignKey(CaseAttempt, on_delete=models.CASCADE)
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
answer = models.ForeignKey(Answer, on_delete=models.CASCADE)
timestamp = models.DateTimeField(auto_now_add=True)
Следует отметить, что для пользователя существует FK. Это используется при определении разрешений.
Вот моя тестовая функция. Для краткости я не включил код для всего класса.
def test_question_retrieve(self):
"""
Check that quiz tracking/ID returns a 200 OK and the content is correct
"""
jim = User(username='jimmy', password='monkey123', email='jimmy@jim.com')
jim.save()
quiz_tracking = QuizTracking(answer=self.answer, case_attempt=self.case_attempt, user=jim)
quiz_tracking.save()
request = self.factory.get(f'/api/v1/progress/quiz-tracking/{quiz_tracking.id}')
# How do I refernce my custom permission using Permission.objects.get() ?
# permission = Permission.objects.get()
# jim.user_permissions.add(permission)
self.test_user.refresh_from_db()
force_authenticate(request, user=jim)
response = self.quiz_detail_view(request, pk=quiz_tracking.id)
print(response.data)
print(jim.id)
print(quiz_tracking.user.id)
self.assertContains(response, 'answer')
self.assertEqual(response.status_code, status.HTTP_200_OK)
В приведенном выше коде я определяю пользователя jim
и quiz_tracking
объект, принадлежащий jim
.
Я создаю свой запрос, force_authenticate
запрос и выполняю мой запрос, и сохраняю ответ в response
.
. Интересно отметить следующее: - jim.id и quiz_tracking. user.id имеют то же значение - я получаю ответ 403 с
{'detail': ErrorDetail(string='You do not have permission to perform this action.', code='permission_denied')}
Возможно, вы заметили, что я прокомментировал permission = Permission.objects.get()
Насколько я понимаю, мне нужно пройти этот класс разрешений, который вмой случай IsUser
. Однако в моей БД нет записи об этом, и, следовательно, Permission.objects.get('IsUSer')
вызов не выполняется.
Итак, у меня следующие вопросы: - Как мне подтвердить свой запрос, чтобы я получил 200 OK? - Нужно ли мне добавлять разрешение моему пользователю в моих тестах, и если да, то какое разрешение и с каким синтаксисом?
Ниже мое представление, а ниже мой файл пользовательских разрешений, определяющий IsUser
class QuickTrackingViewSet(viewsets.ModelViewSet):
serializer_class = QuizTrackingSerializser
def get_queryset(self):
return QuizTracking.objects.all().filter(user=self.request.user)
def get_permissions(self):
if self.action == 'list':
self.permission_classes = [IsUser, ]
elif self.action == 'retrieve':
self.permission_classes = [IsUser, ]
return super(self.__class__, self).get_permissions()
NB Если я закомментирую def get_permissions()
, тогда мой тест пройдет без проблем.
Мой пользовательский permission.py
from rest_framework.permissions import BasePermission
class IsSuperUser(BasePermission):
def has_permission(self, request, view):
return request.user and request.user.is_superuser
class IsUser(BasePermission):
def has_object_permission(self, request, view, obj):
if request.user:
if request.user.is_superuser:
return True
else:
return obj == request.user
else:
return False
Приветствия
С