serializer.is_valid () работает с целочисленными полями, но serializer.save () запрашивает экземпляр модели - PullRequest
1 голос
/ 26 марта 2019

У меня есть отношение многие ко многим в базе данных ma (PK - целые числа). Я автоматически сгенерировал модели django из БД и реализовал простейший сериализатор.

Когда я передаю сериализатору словарь с целыми числами, serializer.is_valid () возвращает True, но serializer.save () говорит, что поля должны быть экземплярами моделей.

Но когда я даю словарь с экземплярами моделей, serializer.is_valid () возвращает False.

data = {'tag_id': 9, 'spending_id': 17}
serializer = TagspendingSerializer(data= data)
serializer.is_valid()
True
serializer.save()

=> ValueError: Невозможно назначить «9»: «Tagspending.tag_id» должен быть экземпляром «Tag».

data = {'tag_id': Tag.objects.get(tag_id= 9), 'spending_id': Spending.objects.get(spending_id= 17)}
serializer = TagspendingSerializer(data= data)
serializer.is_valid()

=> Ложь

Вот моя модель:

class Tagspending(models.Model):
    tag_id = models.ForeignKey(Tag, models.DO_NOTHING, db_column='tag_ID', primary_key=True)
    spending_id = models.ForeignKey(Spending, models.DO_NOTHING, db_column='spending_ID')

    class Meta:
        managed = True
        db_table = 'TagSpending'
        unique_together = (('tag_id', 'spending_id'),)

Вот мой сериализатор:

class TagspendingSerializer(serializers.ModelSerializer):
    class Meta:
        model = Tagspending
        fields = ('tag_id', 'spending_id')

Ответы [ 2 ]

1 голос
/ 26 марта 2019

Я думаю, что есть кое-что, чтобы сделать бит более понятным для вас

Django делает это:

ForeignKey определяет дополнительный атрибут с _id, добавленным к имени поля

В вашей модели есть следующее поле:

tag_id = models.ForeignKey(Tag, models.DO_NOTHING, db_column='tag_ID', primary_key=True)

Но вам не нужно указывать столбец БД или первичный ключ и делать это вместо этого:

tag = models.ForeignKey(Tag, models.DO_NOTHING)

В db столбец db для этого поля будет иметь имя tag_id (как вы хотели бы), а тип будет целочисленным.Вот почему проверка проходит.

Теперь вы можете получить доступ к идентификатору instance.tag_id или instance.tag.id (однако есть разница между этими двумя вызовами - один попадет в БД, если он еще не получен).

Однако в вашем случае «tag_id» - это ForeignKey, для которого требуется экземпляр «Tag».

У вас есть 2 возможных способа решения этой проблемы (при условии, что вы использовали мое предлагаемое изменение для переименования поля)

1) Вы можете использовать tag_id в своем почтовом запросе (теперь, когда имя поля меняется на tag)

2) в вашем сериализаторе, вы можете указать следующее:

tag = serializers.PrimaryKeyRelatedField(queryset=Tag.objects.all())

, и вы можете сделать запрос с помощью

{"tag" : 1 } 

, и это преобразует ваш идентификатор в экземпляр Tag (если он действителен)

0 голосов
/ 26 марта 2019

Кажется, есть ошибка с Django Rest Framework из-за использования tag_id в качестве первичного ключа. Вы должны изменить свою модель, и это лучшая практика, изменяя отношение с Tag как OneToOneField (поскольку это первичный ключ, это отношение уникально, поэтому OneToOneField является более подходящим). Ваш сериализатор должен работать тогда.

Вам также следует рассмотреть возможность переименования полей модели. Нет необходимости вводить суффикс _id.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...