Обновите, если «Email уже существует» в Django Rest Framework - PullRequest
0 голосов
/ 06 февраля 2020

У меня есть объектная модель Candidates в Django Application, которую я получаю из формы во Front End.

Если этот кандидат повторно отправит личные данные с тем же адресом электронной почты, ответ DRF {"email": ["Пользователь с таким адресом электронной почты уже существует."]} и не сохранит форму.

Идея состоит в том, что если этот кандидат отправит форму еще раз с личным адресом электронной почты, и я сохраню ее в своей базе данных, я обновлю личные данные этого кандидата.

Я пытался:

Мой взгляд:

@csrf_exempt
@api_view(['GET', 'POST','PATCH'])
def CandidatesCreate(request, *args, **kwargs):
parser_classes = (FileUploadParser,)

if request.method == 'PATCH' or request.method == 'POST':

    serializer = CandidatesSerializer(data=request.data)
    if serializer.is_valid():
        instance, created = serializer.get_or_create()
        if not created:
            serializer.update(instance, serializer.validated_data)
        return Response(serializer.data, status=status.HTTP_202_ACCEPTED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Мой сериализатор

class CandidatesSerializer(serializers.ModelSerializer):

cv = serializers.FileField(required=False,max_length=None, use_url=True)

class Meta:
    model = Candidates
    fields = (
        'pk', 
        'user',
        'name', 
        'email', 
        'whatever',
        'whatever'
        )

Однако, он не работает. Я не уверен если get_or_create () устарела, если честно. Я не нашел реальной информации об этом.

Ответы [ 3 ]

1 голос
/ 06 февраля 2020

Как и , это решение предлагает , вы можете использовать update_or_create вместо get_or_create, например:

# make sure you use the arguments the right way
instance, created = serializer.update_or_create(email=validated_data.get('email', None), defaults=dict_with_everything_else) 
# instead of
instance, created = serializer.get_or_create()

, просто убедитесь, что аргументы переданы правильно. Когда можно также проверить документы о том, как это сделать

1 голос
/ 07 февраля 2020

Наконец, решение было таким:

from .models import Candidates
from rest_framework import serializers
from django.core.validators import EmailValidator

# first we define the serializers
class CandidatesSerializer(serializers.ModelSerializer):

cv = serializers.FileField(required=False,max_length=None, use_url=True)

class Meta:
    model = Candidates
    fields = (
        'pk', 
        'user',
        'name', 
        'email', 
        'whatever'
        )
    extra_kwargs = {'email': {'validators': [EmailValidator,]},
  }

И мой view.py

@csrf_exempt
@api_view(['GET', 'POST','PATCH'])
def CandidatesCreate(request, *args, **kwargs):
parser_classes = (FileUploadParser,)

if request.method == 'PATCH' or request.method == 'POST':

    serializer = CandidatesSerializer(data=request.data)
    if serializer.is_valid():
        instance, created = Candidates.objects.update_or_create(email=serializer.validated_data.get('email', None), defaults=serializer.validated_data) 
        if not created:
            serializer.update(instance, serializer.validated_data)
        return Response(serializer.data, status=status.HTTP_202_ACCEPTED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

И все работает правильно.

1 голос
/ 06 февраля 2020

У вас есть "unique = True" в поле электронной почты модели, верно? Если это так, я думаю, что сериализатор проверяет, так ли это, когда вы запускаете:

serializer.is_valid()

Чтобы преодолеть это, вы можете попробовать добавить это в мета-класс сериализатора:

extra_kwargs = {
    'email': {'validators': []},
}

И если вы хотите сохранить проверку электронной почты, вы можете попробовать:

from django.core.validators import EmailValidator

class Meta:
    #... your code
    extra_kwargs = {
        'email': {'validators': [EmailValidator,]},
    }
...