我是Django Rest Framework和嵌套序列化程序的新手。我有一个名为OrderSerialiser的ModelSerializer,它包含两个嵌套的ModelSerializer:ProductSerializer和ClientSerializer。
我希望在将订单请求发送到订单CreateAPI时,创建模型客户端和模型产品的新实例(仅当没有现有的实例时)。 我找到的解决方案是覆盖OrderSerializer的create方法。
当没有客户端实例并且产品具有相同的电子邮件和sku时,它工作正常,但它返回错误,表示已存在对象(客户端具有相同的电子邮件和具有相同sku的产品)在另一种情况下,并没有得到那些现有的对象,我注意到在这种情况下没有调用create方法,我认为我必须覆盖serializers.is_valid()
方法,但我不知道我应该做什么确切地说。
models.py
class Client(models.Model):
email = models.EmailField(
verbose_name=_('Email address'),
max_length=255,
unique=True,
primary_key=True
)
first_name = models.CharField(_('first name'), max_length=30)
last_name = models.CharField(_('last name'), max_length=30)
class Product(models.Model):
sku = models.CharField(
verbose_name=_('SKU'),
unique=True,
max_length=120,
primary_key=True
)
name = models.CharField(
verbose_name=_('Name'),
max_length=150
)
url = models.URLField(
verbose_name=_('URL'),
blank=True,
null=True
)
class Order(models.Model):
client = models.ForeignKey(Client)
products = models.ManyToManyField(
Product,
related_name= "orders",
null=True,
blank=True,
)
serializers.py
class ProductSerialiser(serializers.ModelSerializer):
class Meta:
model = Product
fields = ('sku', 'name', 'url')
class ClientSerialiser(serializers.ModelSerializer):
class Meta:
model = Client
fields = ('email','first_name', 'last_name')
class OrderSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.email')
client = ClientSerialiser()
products = ProductSerialiser(many=True, required=False)
class Meta:
model = Order
fields = ('id', 'client', products')
def create(self, validated_data):
client_data = validated_data.pop('client')
try:
client_instance = Client.objects.get(email=client_data['email'])
except ObjectDoesNotExist:
client_instance = Client.objects.create(**client_data)
if 'products' in validated_data:
products_data = validated_data.pop('products')
order_instance = Order.objects.create(client=client_instance, **validated_data)
for product_data in products_data:
try :
product = Product.objects.get(sku=product_data['sku'])
except ObjectDoesNotExist:
product = Product.objects.create(**product_data)
product.orders.add(order_instance)
return order_instance
order_instance = Order.objects.create(client=client_instance, **validated_data)
return order_instance
答案 0 :(得分:0)
Akamee,
我用来解决这类问题的一种方法基本上就是在你的serializers.py里面做
def validate(self, data):
data = super(YourSerializer, self).validate(data)
try:
data['product'] = Product.objects.get(sku='bar')
except Product.DoesNotExist:
data['product'] = Product.object.create(sku='bar')
答案 1 :(得分:0)
这不太理想,但我确实找到了解决问题的解决方案(我等待接受它作为答案,希望别人能做得更好)
我在ClientSerializer中删除了字段电子邮件的验证器,在Productserializer中删除了字段sku,然后手动检查了对象的存在。
在serialzers.py上修改
class ProductSerialiser(serializers.ModelSerializer):
class Meta:
model = Product
fields = ('sku', 'name', 'url')
extra_kwargs = {
'sku': {
'validators': []
}
}
class ClientSerialiser(serializers.ModelSerializer):
class Meta:
model = Client
fields = ('email', 'first_name', 'last_name')
extra_kwargs = {
'email': {
'validators': []
}
}
class OrderSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.email')
client = ClientSerialiser(partial=True)
products = ProductSerialiser(many=True, required=False, partial=True)
class Meta:
model = Order
fields = ('id','client', products')
def create(self, validated_data):
client_data = validated_data.pop('client')
try:
print "**************** client exists ***********************"
client_instance = Client.objects.get(email=client_data['email'])
except ObjectDoesNotExist:
print "**************** creating a client ***********************"
client_instance = Client.objects.create(**client_data)
if 'products' in validated_data:
products_data = validated_data.pop('products')
order_instance = Order.objects.create(client=client_instance, **validated_data)
for product_data in products_data:
try :
print "**************** Product exists ***********************"
product = Product.objects.get(sku=product_data['sku'])
except ObjectDoesNotExist:
print "**************** creating object product ***********************"
product = Product.objects.create(**product_data)
product.orders.add(order_instance)
return order_instance
order_instance = Order.objects.create(client=client_instance, **validated_data)
return order_instance