nic*_*kik 39 django rest django-models django-rest-framework
我User保存了两个不同的模型,UserProfile并且User.现在从API的角度来看,没有人真正关心这两者是不同的.
所以我在这里:
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('url', 'username', 'first_name', 'last_name', 'email')
Run Code Online (Sandbox Code Playgroud)
和
class UserPSerializer(serializers.HyperlinkedModelSerializer):
full_name = Field(source='full_name')
class Meta:
model = UserProfile
fields = ('url', 'mobile', 'user','favourite_locations')
Run Code Online (Sandbox Code Playgroud)
所以在UserPSerializer该领域user只是该资源的链接.但从用户的角度来看,根本没有理由让他知道User.
是否有一些技巧可以将它们混合在一起并作为一个模型呈现给用户,或者我必须以某种方式手动执行此操作.
med*_*nds 33
如果您还覆盖序列化程序上的创建和更新方法,则可以使用@ kahlo方法进行POST和PUT .
给出这样的配置文件模型:
class Profile(models.Model):
user = models.OneToOneField(User)
avatar_url = models.URLField(default='', blank=True) # e.g.
Run Code Online (Sandbox Code Playgroud)
这是一个用户序列化程序,它读取和写入其他配置文件字段:
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)
Run Code Online (Sandbox Code Playgroud)
生成的API根据需要显示扁平用户资源:
GET /users/5/
{
"url": "http://localhost:9090/users/5/",
"username": "test",
"avatar_url": "http://example.com/avatar.jpg"
}
Run Code Online (Sandbox Code Playgroud)
并且您可以avatar_url在POST和PUT请求中包含配置文件的字段.(并且用户资源上的DELETE也将删除其Profile模型,尽管这只是Django的正常删除级联.)
如果用户缺少(在任何更新时),此处的逻辑将始终为用户创建配置文件模型.对于用户和个人资料,这可能就是您想要的.对于其他关系,它可能不是,您需要更改更新或创建逻辑.(这就是为什么DRF 不会自动为您编写嵌套关系的原因.)
bbe*_*ort 12
我刚刚遇到过这个; 我还没有找到一个很好的解决方案,特别是回写我User和UserProfile模型.我目前正在使用手动展平我的序列化程序SerializerMethodField,这是非常恼人的,但它的工作原理:
class UserSerializer(serializers.HyperlinkedModelSerializer):
mobile = serializers.SerializerMethodField('get_mobile')
favourite_locations = serializers.SerializerMethodField('get_favourite_locations')
class Meta:
model = User
fields = ('url', 'username', 'first_name', 'last_name', 'email', 'mobile', 'favourite_locations')
def get_mobile(self, obj):
return obj.get_profile().mobile
def get_favourite_locations(self, obj):
return obj.get_profile().favourite_locations
Run Code Online (Sandbox Code Playgroud)
这是可怕的手动,但你最终得到:
{
"url": "http://example.com/api/users/1",
"username": "jondoe",
"first_name": "Jon",
"last_name": "Doe",
"email": "jdoe@example.com",
"mobile": "701-680-3095",
"favourite_locations": [
"Paris",
"London",
"Tokyo"
]
}
Run Code Online (Sandbox Code Playgroud)
哪个,我猜你正在寻找什么.
我将UserPSerializer在字段不会增长的情况下实现修改:
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('url', 'username', 'first_name', 'last_name', 'email')
class UserPSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.CharField(source='user.url')
username = serializers.CharField(source='user.username')
first_name = serializers.CharField(source='user.first_name')
last_name = serializers.CharField(source='user.last_name')
email = serializers.CharField(source='user.email')
class Meta:
model = UserProfile
fields = ('mobile', 'favourite_locations',
'url', 'username', 'first_name', 'last_name', 'email')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13110 次 |
| 最近记录: |