Отсутствие поля user_id в ModelSerializer фреймворка Django rest приводит к ошибке KeyError

Мой ModelSerializer получает KeyError, когда я вызываю .data на сериализаторе, и я не уверен, как правильно исправить эту ошибку.

Модель AuthToken компании Knox выглядит следующим образом

class AuthToken(models.Model):

    objects = AuthTokenManager()

    digest = models.CharField(
        max_length=CONSTANTS.DIGEST_LENGTH, primary_key=True)
    token_key = models.CharField(
        max_length=CONSTANTS.TOKEN_KEY_LENGTH, db_index=True)
    user = models.ForeignKey(User, null=False, blank=False,
                             related_name='auth_token_set', on_delete=models.CASCADE)
    created = models.DateTimeField(auto_now_add=True)
    expiry = models.DateTimeField(null=True, blank=True)

    def __str__(self):
        return '%s : %s' % (self.digest, self.user)

Я создал сериализатор Model serializer

class AuthTokenResponseSerializer(serializers.ModelSerializer):
    class Meta:
        model = AuthToken
        fields = "__all__"

Однако, когда я создаю token_serializer, я получаю эту ошибку

>> token_serializer.data
*** KeyError: "Got KeyError when attempting to get a value for field `user` on serializer `AuthTokenResponseSerializer`.\nThe serializer field might be named incorrectly and not match any attribute or key on the `dict` instance.\nOriginal exception text was: 'user'."

Я думаю, что получаю эту ошибку, потому что при создании token_serializer не хватает ключа user. Я вижу, что есть ключ user_id, но не user

(Pdb) token_serializer
AuthTokenResponseSerializer(context={'request': <rest_framework.request.Request: POST '/auth/token/'>}, data={'_state': <django.db.models.base.ModelState object>, 'digest': '6b82ac8776113db376d8938a641c3ebdea573b4ab49cb648c171fccc7f4a517e6450cebb21682e26f36562cf7b659f5089957ba49e99c096ebc9eaaa93ab0e53', 'token_key': '872832f8', 'user_id': 34, 'created': None, 'expiry': datetime.datetime(2024, 5, 11, 9, 17, 2, 540546, tzinfo=datetime.timezone.utc)}, partial=True):
    digest = CharField(max_length=128, validators=[<UniqueValidator(queryset=AuthToken.objects.all())>])
    token_key = CharField(max_length=8)
    created = DateTimeField(read_only=True)
    expiry = DateTimeField(allow_null=True, required=False)
    user = PrimaryKeyRelatedField(queryset=User.objects.all())

Моя модель пользователя

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import (
    AbstractBaseUser,
    PermissionsMixin,
    BaseUserManager,
)
from django.utils.translation import gettext_lazy as _
from phonenumber_field.modelfields import PhoneNumberField

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(
        verbose_name=_("email address"), unique=True, max_length=255
    )
    password = models.CharField(
        max_length=128, null=True
    ) 
    first_name = models.CharField(max_length=128, null=True)
    last_name = models.CharField(max_length=128, null=True)
    phone_number = PhoneNumberField(null=True, blank=True)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(default=timezone.now)
    updated_at = models.DateTimeField(default=timezone.now)
  • Ошибка KeyError, с которой вы столкнулись, происходит потому, что сериализатор ожидает наличия поля user в передаваемых ему данных, но в данных которые вы предоставляете, содержат только ключ user_id. Это несоответствие может возникнуть если данные, которые вы сериализуете, поступают из источника, который не точно соответствует структуре, которую ожидает ваш AuthTokenResponseSerializer.

    Чтобы решить эту проблему, вы можете адаптировать AuthTokenResponseSerializer для обработки наличия user_id путем явного сопоставления его с полем поле user. Этого можно достичь, используя PrimaryKeyRelatedField в в вашем сериализаторе и указав атрибут source:

AuthTokenResponseSerializer:

from rest_framework import serializers

class AuthTokenResponseSerializer(serializers.ModelSerializer):
    user = serializers.PrimaryKeyRelatedField(
        queryset=User.objects.all(),
        source='user_id'  # Map the `user_id` field in incoming data to the `user` relationship
    )

    class Meta:
        model = AuthToken
        fields = "__all__"
Вернуться на верх