我有一个 Club 模型和一个 Address 模型。
class Club(models.Model):
name = models.CharField(max_length=100)
owner = models.ForeignKey(UserAccount,on_delete=models.CASCADE,related_name = 'owner_of')
##members = models.ManyToManyField(UserAccount,related_name = 'member_of')
##staff = models.ManyToManyField(UserAccount,related_name = 'staff_of')
def __str__(self):
return f'{self.name}'
class Address(models.Model):
name = models.CharField(max_length=100)
street = models.CharField(max_length=150)
city = models.CharField(max_length=100)
state = models.CharField(max_length=100, blank=True, null=True) # Optional for countries without states
province = models.CharField(max_length=100, blank=True, null=True) # Optional for countries without provinces
country = models.CharField(max_length=50)
postal_code = models.CharField(max_length=20)
club = models.ForeignKey(Club,on_delete=models.CASCADE,related_name = 'address')
def __str__(self):
return f'{self.name}'
他们有受人尊敬的序列化者。
class AddressSerializer(serializers.ModelSerializer):
class Meta:
model = Address
fields = ['id', 'name', 'street', 'city', 'state', 'province', 'postal_code', 'country']
def create(self,validated_data):
user=self.context['user']
club=Club.objects.get(owner=user)
address=Address.objects.create(club=club,**validated_data)
return address
class ClubSerializer(serializers.ModelSerializer):
class Meta:
model = Club
fields = ['id', 'name']
def create(self,validated_data):
user=self.context['user']
club=Club.objects.create(owner=user,**validated_data)
return club
class ClubRegistrationSerializer(serializers.Serializer):
address= AddressSerializer2()
club=ClubSerializer2()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# We pass the "upper serializer" context to the "nested one"
self.fields['address'].context.update(self.context)
self.fields['club'].context.update(self.context)
这是我发布的数据
{
"club":{"name":"someclub"},
"address":{
"name":"Bodrum Location",
"street":"140",
"city":"bodrum",
"state":"california",
"province":"some provence",
"postal_code":"123",
"country":"USA"
}
}
我可以轻松实现我的视图的创建方法并且
这样做:
@action(detail=False,methods=['post'])
def register(self, request):
serializer = ClubRegistrationSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
club_data=serializer.validated_data.pop("club")
address_data=serializer.validated_data.pop("address")
club=Club.objects.create(owner=self.request.user,**club_data)
address=Address.objects.create(club=club,**address_data)
response={}
response['address']=AddressSerializer(address).data
response['club']=ClubSerializer(club).data
return Response(response, status=status.HTTP_201_CREATED)
理想情况下,我不应该实现 ClubRegistrationSerializer 的 create 方法中的所有逻辑。 每个序列化器都应该对自己的序列化器负责。
我应该能够调用 ClubRegistrationSerializer 的 create 方法,并且应该调用 Address 和 Club 序列化器的 create 方法。
我看到的每个示例都处理父序列化器的创建中的所有逻辑。
我已经尝试过
ClubRegistrationSerializer(address=addressOBJ,club=clubOBJ)
像这样
但这引发了异常。
目前我正在创建一个字典并附加模型的值。
这是我想从序列化器获得的响应。
{"club":{"name":"someclub","id":"1"},
"address":{
"id":"1",
"name":"Some Location",
"street":"140",
"city":"San Fran",
"state":"california",
"province":"some province",
"postal_code":"123",
"country":"USA"
}
}
你需要像关系网一样考虑实施。
首先,您可以将
club = models.ForeignKey
字段重构为 OneToOne 关系字段。
然后,您可以摆脱有效负载中的主要字典包装器,并将俱乐部字段平面和地址字段实现为字典。
序列化器
.create
方法仅通过 Model.objects.create
方法在后台创建新实例,因此您不需要真正调用该 serializers.create 方法。字段验证在序列化器中是最重要的 - 他们专门从事这项工作(专业代码中的逻辑至少应该委托给 services.py 文件)。但为了简单起见,让我们留在序列化器中的逻辑。
class ClubSerializer(serializers.ModelSerializer):
address = AddressSerializer()
class Meta:
model = Club
fields = ['id', 'name', 'address']
def create(self, validated_data):
address_data = validated_data.pop("address")
instance = super().create(validated_data)
instance.address = Address.objects.create(club=instance, **address_data)
return instance
查看动作
@action(detail=False,methods=['post'])
def register(self, request):
serializer = ClubSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)