Django REST Framework, создающая объект внешнего ключа внутри сериализатора [duplicate]

Если у вас есть такая конфигурация:

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot "/var/www/example.com"

    <FilesMatch "\.php$">
        SetHandler "proxy:fcgi://127.0.0.1:9000"
    </FilesMatch>
</VirtualHost>

Раскомментируйте следующие строки в вашем httpd.conf

LoadModule proxy_module lib/httpd/modules/mod_proxy.so
LoadModule proxy_fcgi_module lib/httpd/modules/mod_proxy_fcgi.so

Это работает для меня

11
задан Abhinav Desor 19 January 2015 в 04:16
поделиться

2 ответа

SlugRelatedField , предоставленный инфраструктурой Django REST, как и многие связанные с ним поля, предназначен для использования с уже существующими объектами. Поскольку вы ищете ссылку на объекты, которые уже существуют, или объект, который нужно создать, вы не сможете использовать его как есть.

Вам понадобится пользовательский SlugRelatedField, который создает новый объект, если его не существует.

class CreatableSlugRelatedField(serializers.SlugRelatedField):

    def to_internal_value(self, data):
        try:
            return self.get_queryset().get_or_create(**{self.slug_field: data})[0]
        except ObjectDoesNotExist:
            self.fail('does_not_exist', slug_name=self.slug_field, value=smart_text(data))
        except (TypeError, ValueError):
            self.fail('invalid')

class MerchantSerializer(serializers.ModelSerializer):
    phones = CreateableSlugRelatedField(
        many=True,
        slug_field='phone',
        queryset=primitives.Phone.objects.all()
    )

    class Meta:
        model = Merchant
        fields = (
            'merchant_id',
            'name',
            'is_active',
            'phones',
        )

При переключении на get_or_create объект номера телефона будет создан, если он еще не существует. Возможно, вам придется настроить его, если на модели будут созданы дополнительные поля.

27
ответ дан rinat.io 19 August 2018 в 19:52
поделиться
  • 1
    Благодаря! Это сделал трюк. Теперь кажется настолько очевидным, что он ожидает, что SlugRelatedField будет уже создан. – Abhinav Desor 18 January 2015 в 18:21
  • 2
    Это отличное решение. Если кто-то ищет дополнительную настройку, перейдите по этой ссылке: django-rest-framework.org/api-guide/fields Например, я обнаружил, что добавление обязательного = True & amp; allow_null = True, сделал это правильным решением для меня. – rahulthakur319 21 September 2017 в 21:50
  • 3
    Не могли бы вы добавить необходимые примеры импорта в свой пример? В частности smart_text и ObjectDoesNotExist. – Matt 18 December 2017 в 21:20
  • 4
    Я также пытаюсь написать тест, который охватывает два исключения. Учитывая, что вы используете get_or_create, как можно повысить ObjectDoesNotExist? – Matt 19 December 2017 в 03:37

Вы должны указать значение для поля телефона объекта Phone. Если вы хотите создать объект телефона без указания значения для полевого телефона, вам нужно включить пустые и пустые поля.

phone = models.CharField(max_length=255,null=true,blank=true)

Если у вас по-прежнему возникают проблемы, убедитесь, что данные сообщения содержат необходимые поля. Вы можете использовать ipdb для этого.

1
ответ дан Piero Simoni Urbino 19 August 2018 в 19:52
поделиться
  • 1
    Привет. Я добавил запрос и ответ. Я прохожу по номерам телефонов (которые, как я знаю, должны войти в поле «телефон» телефона модели телефона). – Abhinav Desor 18 January 2015 в 14:22
  • 2
    похоже, что вы пытаетесь выполнить неправильный object.get в views.py. опубликуйте свой взгляд. – Piero Simoni Urbino 18 January 2015 в 16:31
Другие вопросы по тегам:

Похожие вопросы: