使用SlugRelatedField创建和保存外键对象 [英] Creating and saving foreign key objects using a SlugRelatedField

查看:2596
本文介绍了使用SlugRelatedField创建和保存外键对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始使用Django REST框架,我在保存外键时遇到麻烦。我有一个商户模型和一个电话模型。 Phone 具有商家的外键。在 POST 请求商家时,我想创建电话请求中提供的数字的对象。但是当我提供电话号码时,它给我以下错误


电话= 0123456789的对象不存在。


我只想让它创建 Phone 对象本身。以下是我使用的模型:

 类商家(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,
名称:Abhinav,
is_active:true,
电话:[
0123456789,
9876543210
]

这是响应:



400不良请求

  {手机:[对象与手机= 0123456789不存在。]} 


解决方案

Django REST框架提供的 SlugRelatedField ,与许多相关字段一样,被设计为与已经存在的对象一起使用。由于您正在寻找引用已存在的对象或需要创建的对象,因此您将无法按原样使用。



您将需要一个自定义 SlugRelatedField ,当不存在时创建新对象。

  class CreatableSlugRelatedField(serializers.SlugRelatedField):

def to_internal_value(self,data):
try:
return self.get_queryset()。get_or_create(** {
除了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()


cla ss Meta:
model = Merchant
fields =(
'merchant_id',
'name',
'is_active',
'phones',

切换到 get_or_create ,如果没有,电话号码对象将被创建已经存在。如果需要在模型上创建其他字段,则可能需要进行调整。


I've just started with Django REST framework and I'm having trouble with saving foreign keys. I have a Merchant model and a Phone model. The Phone has a foreign key to Merchant. When making a POST request to Merchant, I want to create Phone objects for the numbers provided in the request. But when I supply the phone numbers, it gives me the following error

Object with phone=0123456789 does not exist.

I just want it to create the Phone object itself. Here are the models that I am using:

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'

And here is the view and serializer that I am using them with

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

Here's what my request body looks like:

{
    "merchant_id": "emp011",
    "name": "Abhinav",
    "is_active": true,
    "phones": [
        "0123456789",
        "9876543210"
    ]
}

Here's the response:

400 Bad Request

{"phones":["Object with phone=0123456789 does not exist."]}

解决方案

The SlugRelatedField provided by Django REST framework, like many of the related fields, is designed to be used with objects that already exist. Since you are looking to reference objects which already exist, or object which need to be created, you aren't going to be able to use it as-is.

You will need a custom SlugRelatedField that creates the new object when one doesn't exist.

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',
        )

By switching to get_or_create, the phone number object will be created if one doesn't already exist. You may need to tweak this if there are additional fields that have to be created on the model.

这篇关于使用SlugRelatedField创建和保存外键对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆