Как заставить поле базы данных принимать только одно значение для пользователя - PullRequest
2 голосов
/ 30 сентября 2019

Я пытаюсь связать пользователя с учетной записью PayPal и только с одной. Это означает, что если в этом поле есть значение, запрос на публикацию должен вернуть «Там уже есть значение» или просто не работать (код состояния возврата 400).

Я пытался использоватьUniqueTogetherValidator в сериализаторе и использование и идентификатор, а также. Проблема с этим подходом состоит в том, что для него требуется поле 'id' в запросе на публикацию, которое еще не сгенерировано (идентификатор автоматически генерируется платформой).

Вот что я пытаюсь сделать с моимреализация сериализатора

class PaypalAffiliateSerializer(serializers.ModelSerializer):
    # id = serializers.ReadOnlyField(required=False)

    class Meta:
        model = PaypalAffiliate
        validators = [
            UniqueTogetherValidator(
                queryset=PaypalAffiliate.objects.all(),
                fields=['paypal', 'id']
            )
        ]
        fields = ('paypal', 'id')

и вот моя модель

class PaypalAffiliate(models.Model):
    paypal = models.EmailField()
    affiliate = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.paypal

    class Meta:
        unique_together = ('paypal', 'affiliate')

А вот мое мнение

class PaypalAffiliateViewSet(mixins.CreateModelMixin,
                             mixins.UpdateModelMixin,
                             viewsets.GenericViewSet,
                             mixins.RetrieveModelMixin,
                             mixins.ListModelMixin):
    queryset = PaypalAffiliate.objects.all()
    serializer_class = PaypalAffiliateSerializer

    def get_queryset(self):
        queryset = super().get_queryset()
        queryset = queryset.filter(affiliate=self.request.user)
        return queryset

    def perform_create(self, serializer):
        serializer.save(affiliate=self.request.user)

    def perform_update(self, serializer):
        serializer.save(affiliate=self.request.user)

Как я могу заставить поле электронной почты PayPal принимать только одинзначение для каждого пользователя?

1 Ответ

1 голос
/ 30 сентября 2019

Если вы просто наберете unique=True в поле, то оно должно работать, оно увеличит IntegrityError в сериализаторе

class PaypalAffiliate(models.Model):
    paypal = models.EmailField(unique=True)
    affiliate = models.OneToOneField(User, on_delete=models.CASCADE)

. Вы можете поймать IntegrityError и вернуть желаемый ответ.

Обновление

Если вы хотите не более одной PaypalAffilate записи на пользователя, как уже упоминалось, используйте OneToOneField

class PaypalAffiliate(models.Model):
    paypal = models.EmailField()
    affiliate = OneToOneField(User, on_delete=models.CASCADE)

Ваше мнение также неверно, я сделалне пытайтесь использовать Mixins, который вы делали, но вы должны делать это, передавая данные сериализатору для вызова is_valid() для проверки

serializer = PaypalAffiliateSerializer(data=request.data)
if serializer.is_valid():
  # return 200 OK here
else:
  #return serializer.errors 

См. this

...