2017-06-02 2 views
0

Ich habe einen einfachen API-Endpunkt. Es dauert zwei Post-Parameter, die kein Modell in meinem System entsprechen: user_id und codeDjango/DRF: Warum bekomme ich einen Modellfehler für einen nicht modellhaften Serialisierer?

Mein Serializer:

class ConfirmationCodeSerializer(serializers.Serializer): 
    user_id = serializers.CharField(max_length=36) 
    code = serializers.CharField(max_length=7) 

    def validate(self, attrs): 
     try: 
      user = User.objects.get(pk=attrs['user_id']) 
     except (ValidationError, User.DoesNotExist): 
      raise serializers.ValidationError("invalid user_id") 
     try: 
      confirmation_code = SignupConfirmationCode.objects.get(
        user_id=attrs['user_id']) 
     except (ValidationError, SignupConfirmationCode.DoesNotExist): 
      raise serializers.ValidationError("confirmation record not found") 

     if confirmation_code.code != attrs['code']: 
      raise serializers.ValidationError("incorrect user_id and/or code") 

     if user.is_active: 
      raise serializers.ValidationError("user already confirmed") 

     return attrs 

    def create(self, validated_data): 
     print(validated_data) 
     user = User.objects.get(pk=validated_data['user_id']) 
     user.is_active = True 
     user.save() 
     confirmation_code = SignupConfirmationCode.objects.get(
      user_id=user.id) 
     confirmation_code.delete() 
     return user 

meiner Sicht:

class confirmation_code(APIView): 
    """ 
    send confirmation code to validate and activate a new user 
    account 
    """ 
    permission_classes = ([AllowAny]) 

    def post(selfself, request, format=None): 
     serializer = ConfirmationCodeSerializer(data=request.data) 
     if serializer.is_valid(): 
      serializer.save() 
      return Response(serializer.data, status=status.HTTP_200_OK) 
     return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 

wenn es runs- es tut es die Aufgabe, die Der Bestätigungscode wird gelöscht, und der Benutzerdatensatz wird aktualisiert, aber ich erhalte diesen Fehler:

Meine Frage ist, warum versucht das System user_id, die eine meiner Post-Parameter ist, in ein User Modell, das nicht in der Klasse Meta definiert ist, und was kann ich dagegen tun?

voll Stacktrace:

internal Server Error: /int_api/v1/signup/confirmationcode/ 
Traceback (most recent call last): 
    File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/rest_framework/fields.py", line 445, in get_attribute 
    return get_attribute(instance, self.source_attrs) 
    File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/rest_framework/fields.py", line 104, in get_attribute 
    instance = getattr(instance, attr) 
AttributeError: 'User' object has no attribute 'user_id' 

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
    File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner 
    response = get_response(request) 
    File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response 
    response = self.process_exception_by_middleware(e, request) 
    File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response 
    response = wrapped_callback(request, *callback_args, **callback_kwargs) 
    File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view 
    return view_func(*args, **kwargs) 
    File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/django/views/generic/base.py", line 68, in view 
    return self.dispatch(request, *args, **kwargs) 
    File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/rest_framework/views.py", line 489, in dispatch 
    response = self.handle_exception(exc) 
    File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/rest_framework/views.py", line 449, in handle_exception 
    self.raise_uncaught_exception(exc) 
    File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/rest_framework/views.py", line 486, in dispatch 
    response = handler(request, *args, **kwargs) 
    File "/Users/my_name/dev/my_app-t2/my_app_backend/v1_int_api/views.py", line 83, in post 
    return Response(serializer.data, status=status.HTTP_200_OK) 
    File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/rest_framework/serializers.py", line 534, in data 
    ret = super(Serializer, self).data 
    File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/rest_framework/serializers.py", line 263, in data 
    self._data = self.to_representation(self.instance) 
    File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/rest_framework/serializers.py", line 488, in to_representation 
    attribute = field.get_attribute(instance) 
    File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/rest_framework/fields.py", line 464, in get_attribute 
    raise type(exc)(msg) 
AttributeError: Got AttributeError when attempting to get a value for field `user_id` on serializer `ConfirmationCodeSerializer`. 
The serializer field might be named incorrectly and not match any attribute or key on the `User` instance. 
Original exception text was: 'User' object has no attribute 'user_id'. 
+0

Stacktrace? Weißt du, wo das geworfen wird? – theWanderer4865

+0

Hinzufügen von Stacktrace zum Posten. – JasonGenX

Antwort

0

Dies liegt daran, dass Sie Benutzerinstanz in create Methode zurückzukehren. Von defaultto_representation Methode versuchen, Ergebnis der create oder update Methode mit serilizer Felder (user_id und Code in Ihrem Fall) zu serialisieren.

zu beheben Fehler versuchen to_representation wie folgt zu definieren:

def to_representation(self, instance): 
    serializer = UserSerializer(instance) 
    return serializer.data 
+0

Danke. Das hat den Trick gemacht – JasonGenX

Verwandte Themen