Как задать логику, чтобы только сопровождающий событие мог дать отзыв о событии в drf?

я новичок в drf

Я управляю системой управления событиями, я пытался подсчитать участников мероприятия и только участники мероприятия могут просматривать отзывы о мероприятии. Я столкнулся с проблемой в модели отзывов.

я управляю посетителями в модели Event с помощью поля ManyToManyField.

вот мои модели,

class Event(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="event_user")
    attendees = models.ManyToManyField(User, blank=True, related_name='attendees_user')
    venue = models.ForeignKey(Venue, on_delete=models.CASCADE, related_name='venue_user')
    event_type = models.CharField(max_length=50, choices=event_type)
    event_name = models.CharField(max_length=25)
    start_time = models.DateTimeField(blank=False, null=True)
    end_time = models.DateTimeField(blank=False, null=True)

    def __str__(self):
        return f'{self.venue} - {self.event_name}'

class Reviews(models.Model):
    reviewer = models.ForeignKey(User, on_delete=models.CASCADE, related_name="reviewer_user")
    event = models.ForeignKey(Event, on_delete=models.CASCADE, related_name="event")
    review = models.TextField()


    class Meta:
        verbose_name_plural = "Reviews"

    def __str__(self):
        return f'{self.reviewer} -- {self.review} -- {self.event}'

здесь мои сериализаторы

class EventSerializer(serializers.ModelSerializer):
    images = serializers.ListField(
        child=serializers.FileField(allow_empty_file=True, use_url=True, ), required=False)

    class Meta:
        model = Event
        fields = (
            'id', 'user', 'attendees', 'venue', 'event_type', 'event_name', 'start_time', 'end_time',
            'images')

    def create(self, validated_data):
        uploaded_data = validated_data.pop('images')
        attendees = validated_data.pop('attendees')
        instance = Event.objects.create(**validated_data)
        instance.attendees.set(attendees)
        instance.save()
        for pics in uploaded_data:
            EventImages.objects.create(event=instance, event_pics=pics)
        return instance

    def to_representation(self, instance):
        response = super(EventSerializer, self).to_representation(instance)
        response["venue_name"] = instance.venue.venue_name
        response["start_time"] = instance.start_time.strftime("%d/%m/%Y, %H:%M:%S")
        response["end_time"] = instance.end_time.strftime("%d/%m/%Y, %H:%M:%S")
        return response

    def validate(self, data):

        if data.get("start_time") > data.get("end_time"):
            raise serializers.ValidationError("'End time' must be after 'Start time'.")
        else:
            pass

        if Event.objects.filter(
                (Q(venue=data['venue']) &
                 Q(start_time__range=(data['start_time'], data['end_time']))) |
                (Q(venue=data['venue']) &
                 Q(end_time__range=(data['start_time'], data['end_time'])))
        ):
            raise serializers.ValidationError("Venue is booked for this time slot")
        else:
            return data

class ReviewSerializer(serializers.ModelSerializer):

    class Meta:
        model = Reviews
        fields = ('id', 'reviewer', 'event', 'review')

    def validate(self, request):
        data = request.data
        event = Event.objects.filter(id=request.get("event").id).first()
        user = User.objects.filter(id=request.get("user").id).first()
        if user and event and user in event.attendees:
            return data
        else:
            raise serializers.ValidationError("only participants can review !!")

вот мой набор взглядов,

class EventViewSet(viewsets.ModelViewSet):
    queryset = Event.objects.all()
    serializer_class = EventSerializer

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            instance = serializer.save()
            return_serializer = EventSerializer(instance)
            headers = self.get_success_headers(return_serializer.data)
            return Response(return_serializer.data, status=status.HTTP_201_CREATED, headers=headers)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def partial_update(self, request, *args, **kwargs):
        serializer = EventSerializer(instance=Event(), data=request.data, partial=True)
        if serializer.is_valid():
            instance = serializer.save()
            return_serializer = VenueSerializer(instance)
            headers = self.get_success_headers(return_serializer.data)
            return Response(return_serializer.data, headers=headers, status=status.HTTP_202_ACCEPTED)


class ReviewViewSet(viewsets.ModelViewSet):
    queryset = Reviews.objects.all()
    serializer_class = ReviewSerializer

я пытаюсь управлять количеством участников и рецензиями на мероприятие.

вы можете использовать drf-nested-routers это поможет получить урлы в таком виде:

/events/id_event/reviews
/events/id_event/attendees

urls.py:

router = DefaultRouter()
router.register(r'events', EventViewSet, basename='events')
nested_router = NestedDefaultRouter(router, r'events', lookup='event')
nested_router.register(r'reviews', ReviewViewSet, basename='reviews')
nested_router.register(r'attendees', Attendees ViewSet, basename='attendees')

views.py

class ReviewViewSet(viewsets.ModelViewSet):
    queryset = Reviews.objects.all()
    serializer_class = ReviewSerializer
    
    def get_queryset(self):
        if self.kwargs.get('event_pk'):
            return super(ReviewViewSet, self).get_queryset().filter(event__id=self.kwargs.get('event_pk'))
        return super(ReviewViewSet, self).get_queryset()

Тогда вы можете сделать несколько стрингов с посетителями.

Вернуться на верх