我刚开始使用Django REST框架,但是在保存外键时遇到了麻烦。我有一个Merchant模特和一个Phonemodel。的Phone外键为Merchant。向发出POST请求时Merchant,我想为Phone请求中提供的数字创建对象。但是,当我提供电话号码时,会出现以下错误
Merchant
Phone
POST
电话= 0123456789的对象不存在。
我只希望它创建Phone对象本身。这是我正在使用的模型:
class Merchant(models.Model): merchant_id = models.CharField(max_length=255) name = models.CharField(max_length=255) is_active = models.BooleanField(default=True) class Meta: managed = True db_table = 'merchant' # Managers objects = models.Manager() active = managers.ActiveManager() class Phone(models.Model): phone = models.CharField(max_length=255) merchant = models.ForeignKey('merchant.Merchant', related_name='phones', blank=True, null=True) class Meta: managed = True db_table = 'phone'
这是我正在使用它们的视图和序列化器
class MerchantSerializer(serializers.ModelSerializer): phones = serializers.SlugRelatedField( many=True, slug_field='phone', queryset=primitives.Phone.objects.all()) class Meta: model = Merchant fields = ( 'merchant_id', 'name', 'is_active', 'phones', ) class MerchantViewSet(viewsets.ModelViewSet): queryset = Merchant.active.all() serializer_class = MerchantSerializer
这是我的请求正文:
{ "merchant_id": "emp011", "name": "Abhinav", "is_active": true, "phones": [ "0123456789", "9876543210" ] }
这是回应:
400错误的要求
{"phones":["Object with phone=0123456789 does not exist."]}
该SlugRelatedField由Django的REST框架,像许多相关领域的提供,旨在与已经存在的对象使用。由于你要参考已存在的对象或需要创建的对象,因此你将无法原样使用它。
SlugRelatedField
你将需要一个自定义项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,则将创建电话号码对象(如果尚不存在)。如果必须在模型上创建其他字段,则可能需要进行调整。