Я изучаю DRF, и теперь я столкнулся с проблемой, которая остановила меня на несколько дней. Приложение представляет собой приложение класса Zumba, и я использую DRF для создания API поверх него. Часть, которую я пытаюсь построить прямо сейчас, это часть, в которой пользователь может добавить себя в класс zumba (поэтому он должен иметь возможность обновлять множество полей). Что бы я хотел, чтобы API делал, когда пользователь регистрируется самк классу (PUT или PATCH), это взять его имя пользователя, которое мы получаем из аутентификации, и добавить его в поле «myusers». Но так как PUT пуст, API продолжает жаловаться, что требуются «myusers».
Есть ли способ сообщить API, что "myusers" не требуется в запросе PUT, поскольку он извлекается из токена аутентификации? (Если я вручную создаю запрос PUT с "myusers": [{"id": 9}]
в теле, он работает, но я бы не хотел добавлять эту сторону клиента, поскольку передаваемые данные даже не используются.)
Сериализатор (всеПоля только для чтения, чтобы убедиться, что пользователь не может их обновить):
class UserActivityClassesSerializer(serializers.ModelSerializer):
activitytypename = serializers.SlugRelatedField(source='activitytype', slug_field='name', read_only=True)
activitytype = ActivityTypeSerializer(read_only=True)
myusers = MyUsersSerializer(many=True) # serializers.HyperlinkedRelatedField(many=True, view_name='myusers-detail', read_only=True)
uri = serializers.SerializerMethodField(read_only=True)
class Meta:
model = Activity
fields = [
'uri',
'id',
'name',
'date',
'activitytype',
'activitytypename',
'status',
'myusers',
]
read_only_fields = [
'uri',
'id',
'name',
'date',
'activitytype',
'activitytypename',
'status',
]
def get_uri(self, obj):
request = self.context.get('request')
return api_reverse("api-activities:classes-detail", kwargs={"id": obj.id}, request=request)
Представление
class ActivityViewSet(viewsets.ModelViewSet):
permission_classes = [permissions.IsAuthenticated]
queryset = Activity.objects.all()
lookup_field = 'id'
def get_serializer_class(self):
if self.request.user.is_staff or self.action == 'create':
return AdminActivityClassesSerializer
else:
return UserActivityClassesSerializer
def perform_update(self, serializer):
instance = self.get_object()
request = serializer.context['request']
auth_user = request.user
qs = instance.myusers.filter(id=auth_user.id)#we verify is the user is already registered, and if yes, we remove him
if qs:
print('delete')
instance.myusers.remove(auth_user)
return instance
else:
result = verify_valid_season_pass(auth_user, instance)
if result == 1:
print('add')
instance.myusers.add(auth_user.id)
else:
raise serializers.ValidationError("No valid seasonpass found.")
Модель, которая обновляется:
class Activity(models.Model):
CLOSE = 0
OPEN = 1
ACTIVITY_STATUS_CHOICES = [
(CLOSE, 'Closed'),
(OPEN, 'Open'),
]
name = models.CharField('Activity Name', max_length=64, blank=False, null=False)
date = models.DateTimeField('Start Date & Time', blank=False, null=False)
activitytype = models.ForeignKey(ActivityType, blank=False, null=False, default=1, on_delete=models.DO_NOTHING)
status = models.IntegerField('Status', choices=ACTIVITY_STATUS_CHOICES, default=OPEN,) # 1 = open, 0 = closed
myusers = models.ManyToManyField("users.User")
def __str__(self):
return self.name
Любые подсказки?