DRF Foreignkey сериализация - PullRequest
0 голосов
/ 21 октября 2019

Я не могу сохранить модель с полем Foreignkey.

Благодаря "азудо" проблема решена. Решение ниже

Например у меня есть простые модели:

class User(AbstractUser):
    class Meta:
        pass

    email_validator = EmailValidator()
    username = models.CharField('Name', max_length=150, )
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    email = models.EmailField('Email', blank=True, unique=True, validators=[email_validator], )
    ...

class Package(models.Model):

    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='packages')
    description = models.CharField('Description', max_length=256, default='description')
    weight = models.CharField('weight', max_length=256, default='weight')
    ...

Просмотр (пользователь гарантированно будет в запросе):

@api_view(["POST"])
def test(request):
    data = request.data
    data['user'] = User.objects.get(id=request.user.id)
    serializer = PackageSerializer(data=data)
    if serializer.is_valid():
        serializer.save()
        return JsonResponse(serializer.data)
    else:
        return JsonResponse(serializer.errors)

МойСериализаторы:

class UserSerializer(ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'


class PackageSerializer(ModelSerializer):

    class Meta:
        model = Package
        fields = (
            'user', 'description', 'weight', 'dimensions', 'estimated_shipping_cost', 'deliver_to_date')

    def to_representation(self, instance):
        self.fields['user'] = UserSerializer(many=False, read_only=True)
        self.fields['where_from'] = LocationSerializer(many=False, read_only=True)
        self.fields['destination'] = LocationSerializer(many=False, read_only=True)
        return super().to_representation(instance)

    def create(self, validated_data):
        user = User.objects.get(validated_data.pop('user'))
        package = Package.objects.create(user=user, **validated_data)
        return package

json в запросе:

{
    "description": "Some package",
    "weight": "12",
}

Итак, у меня есть пользователь в базе данных, и я хочу создать пакет для него. Но в переопределенных create в PackageSerializer, validated_data не имеет user. Пожалуйста, объясните, что я делаю не так.

Версии django и drf:

django==2.2.4
djangorestframework==3.10.2   

Решение:

Сериализатор:

class PackageSerializer(ModelSerializer):
    user = UserSerializer(many=False, read_only=True)

    class Meta:
        model = Package
        fields = (
            'user', 'description', 'weight', 'dimensions', 'estimated_shipping_cost', 'deliver_to_date')

    def create(self, validated_data):
        user = User.objects.get(validated_data.pop('user'))
        package = Package.objects.create(user=user)
        return package

Вид:

@api_view(["POST"])
def create_package(request):
    data = request.data
    serializer = PackageSerializer(data=data)
    if serializer.is_valid():
        serializer.save(user=request.user)
        return JsonResponse(serializer.data)
    else:
        return JsonResponse(serializer.errors)

1 Ответ

1 голос
/ 21 октября 2019

DRF будет игнорировать включенные поля, помеченные как доступные только для чтения, поэтому вызывающая сторона не может включать данные только для чтения. Если вы хотите включить дополнительные атрибуты, просто передайте их в качестве аргументов ключевых слов для сохранения: https://www.django -rest-framework.org / api-guide / serializers / # routing-Additional-attribute-to-save

например

@api_view(["POST"])
def test(request):
    data = request.data
    serializer = PackageSerializer(data=data)
    if serializer.is_valid():
        serializer.save(user=request.user)
        return JsonResponse(serializer.data)
    else:
        return JsonResponse(serializer.errors)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...