Django Rest框架使OnetoOne关系船感觉像是一个模型 [英] Django Rest Framework make OnetoOne relation ship feel like it is one model
问题描述
我的用户
保存在两种不同的模型中, UserProfile
和用户
。从API的角度来看,没有人真的在乎这两者是不同的。
所以这里我有:
class UserSerializer(serializers.HyperlinkedModelSerializer )
class Meta:
model = User
fields =('url','username','first_name','last_name','email')
和
class UserPSerializer serializer.HyperlinkedModelSerializer):
full_name = Field(source ='full_name')
class Meta:
model = UserProfile
fields =('url','mobile','user ','favourite_locations')
所以在 UserPSerializer
字段用户
只是指向该资源的链接。但是,从用户角度来看,根本就没有理由知道 User
。
有没有一些
如果您还重写序列化程序上的创建和更新方法,您可以使用 @ kahlo的方法POST和PUT。 / p> 给出一个这样的配置文件模型: 这是一个用户串行器,可以读取和写入附加的配置文件字段: 所需的API会根据需要提供一个平面的用户资源: 您可以在POST和PUT请求中包含配置文件的 这里的逻辑将始终为用户创建配置文件模型(如果有任何更新)。用户和个人资料,这可能是你想要的。对于其他关系,它可能不是,您需要更改更新或创建逻辑。 (这就是为什么DRF doesn不要通过嵌套关系自动写入。) I have my So here I have: and So in Is there some tricks with which I can just mash them together and present them to the user as one model or do I have to do this manually somehow. You can POST and PUT with @kahlo's approach if you also override the create and update methods on your serializer. Given a profile model like this: Here's a user serializer that both reads and writes the additional profile field(s): The resulting API presents a flat user resource, as desired: and you can include the profile's The logic here will always create a Profile model for the User if it's missing (on any update). With users and profiles, that's probably what you want. For other relationships it may not be, and you'll need to change the update-or-create logic. (Which is why DRF doesn't automatically write through a nested relationship for you.) 这篇关于Django Rest框架使OnetoOne关系船感觉像是一个模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
模型):
user = models.OneToOneField(User)
avatar_url = models.URLField(default ='',blank = True)#eg
类UserSerializer(serializers.HyperlinkedModelSerializer):
#用户配置文件中的一个字段:
avatar_url = serializers.URLField source ='profile.avatar_url',allow_blank = True)
class Meta:
model =用户
fields =('url','username','avatar_url')
def create(self,validated_data):
profile_data = validated_data.pop('profile',None)
user = super(UserSerializer,self).create(validated_data)
self.update_or_create_profile(user,profile_data)
return user
def update(self,instance,validated_data):
profile_data = validated_data.pop('profile',None)
self.update_or_create_profile(instance,profile_data)
return super(UserSerializer,self).update(inst ance,validated_data)
def update_or_create_profile(self,user,profile_data):
#如果用户缺少一个,这总是创建一个配置文件;
#更改逻辑,如果这不适合您的应用程序
Profile.objects.update_or_create(user = user,defaults = profile_data)
GET / users / 5 /
{
url:http:// localhost:9090 / users / 5 /,
username:test,
avatar_url:http://example.com/avatar.jpg
}
avatar_url
字段。 (和用户资源上的DELETE也会删除其配置文件模型,虽然这只是Django的正常删除级联。)
User
saved in two different models, UserProfile
and User
. Now from API perspective, nobody really cares that these two are different. class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('url', 'username', 'first_name', 'last_name', 'email')
class UserPSerializer(serializers.HyperlinkedModelSerializer):
full_name = Field(source='full_name')
class Meta:
model = UserProfile
fields = ('url', 'mobile', 'user','favourite_locations')
UserPSerializer
the field user
is just a link to that resource. But form a User perspective there is really no reason for him to know about User
at all.class Profile(models.Model):
user = models.OneToOneField(User)
avatar_url = models.URLField(default='', blank=True) # e.g.
class UserSerializer(serializers.HyperlinkedModelSerializer):
# A field from the user's profile:
avatar_url = serializers.URLField(source='profile.avatar_url', allow_blank=True)
class Meta:
model = User
fields = ('url', 'username', 'avatar_url')
def create(self, validated_data):
profile_data = validated_data.pop('profile', None)
user = super(UserSerializer, self).create(validated_data)
self.update_or_create_profile(user, profile_data)
return user
def update(self, instance, validated_data):
profile_data = validated_data.pop('profile', None)
self.update_or_create_profile(instance, profile_data)
return super(UserSerializer, self).update(instance, validated_data)
def update_or_create_profile(self, user, profile_data):
# This always creates a Profile if the User is missing one;
# change the logic here if that's not right for your app
Profile.objects.update_or_create(user=user, defaults=profile_data)
GET /users/5/
{
"url": "http://localhost:9090/users/5/",
"username": "test",
"avatar_url": "http://example.com/avatar.jpg"
}
avatar_url
field in both POST and PUT requests. (And DELETE on the user resource will also delete its Profile model, though that's just Django's normal delete cascade.)