Django 如何从 ManyToManyField 序列化并列出所有
Django How to Serialize from ManyToManyField and List All
我正在使用 Django 1.9.1 开发移动应用程序后端我实现了关注者模型,现在我想列出用户的所有关注者,但我目前坚持这样做。我也使用 Django Rest 框架。
这是我的 UserProfile 模型
class UserProfile(models.Model):
# Linking UserProfile to User model.
user = models.OneToOneField(User)
city = models.CharField(null=True, max_length=30, blank=True)
gender = models.CharField(null=True, max_length=10, blank=True) # m for male, f for female
# TODO: Fix the picture later.
# picture = models.ImageField(upload_to='profile_images', blank=True)
age = models.IntegerField(null=True, blank=True)
caption = models.CharField(null=True, max_length=40, blank=True)
following_count = models.IntegerField(default=0)
follower_count = models.IntegerField(default=0)
post_count = models.IntegerField(default=0)
like_count = models.IntegerField(default=0)
date = models.DateTimeField(default=datetime.now(), blank=True)
is_protected = models.BooleanField(default=False)
is_facebook_created_user = models.BooleanField(default=False)
facebook_id = models.CharField(default='', blank=True, max_length=350)
picture_url = models.URLField(blank=True, max_length=100, null=True)
followings = models.ManyToManyField('self', related_name='following', symmetrical=False)
followers = models.ManyToManyField('self', related_name='follower', symmetrical=False)
blocking = models.ManyToManyField('self', related_name='block', symmetrical=False)
blocked_by = models.ManyToManyField('self', related_name='blocked', symmetrical=False)
def block_user(self,username):
other = UserProfile.objects.get(user__username=username)
if not self.is_blocking(username):
self.blocking.add(other)
other.blocked_by.add(self)
return True
else:
return False
def unblock_user(self, username):
other = UserProfile.objects.get(user__username=username)
if self.is_blocking(username):
self.blocking.remove(other)
other.blocked_by.remove(self)
return True
else:
return False
def follow_user(self, username):
other = UserProfile.objects.get(user__username=username)
if not self.is_following(username):
self.followings.add(other)
self.following_count = self.followings.all().count()
self.save()
other.followers.add(self)
other.follower_count = other.followers.all().count()
other.save()
return True
else:
return False
def unfollow_user(self, username):
other = UserProfile.objects.get(user__username=username)
if self.is_following(username):
self.followings.remove(other)
self.following_count = self.followings.all().count()
self.save()
other.followers.remove(self)
other.follower_count = other.followers.all().count()
other.save()
return True
else:
return False
def is_blocking(self,username):
return self.blockings.all().filter(user__username=username).exists()
def is_blocked_by(self,username):
return self.blocked_by.all().filter(user__username=username).exists()
def is_following(self, username): #returns Bool
return self.followings.all().filter(user__username=username).exists()
def is_followed_by(self, username): #returns Bool
return self.followers.all().filter(user__username=username).exists()
def __unicode__(self):
return self.user.username
def get_token(self):
try:
token = Token.objects.get(user_id=self.user_id)
except:
token = 'error'
return token
def get_username(self):
return self.user.username
如您所见,我使用 ManyToManyField 作为关注者。现在我想列出一个用户的关注者,但我不想只列出他们的所有信息,因为这是不必要的。我只想列出他们的用户名,因为不需要完整的信息,这只是一种浪费。
这是我的粉丝视图。
@api_view(['GET'])
def get_followers(request):
username = request.query_params.get('username', None)
if username is not None:
if UserProfile.objects.all().filter(user__username=username).exists():
wanted = UserProfile.objects.get(user__username=username)
followers = wanted.followers.all()
serializer = FollowerSerializer(followers)
return JsonResponse(serializer.data)
else:
return JsonResponse({"result": "user_does_not_exist"})
else:
#TODO: return current user's followers
return JsonResponse({"result": "provide_username"})
我还为用户的关注者添加了一个序列化程序。
class FollowerSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
field = ('followers',)
问题是,它只列出了所有用户信息,没有提供用户名,但它只列出了他们的 ID,我无能为力。
我忘了说我确实考虑过使用 ListAPIView,但我无法通过它获取用户名参数。如果有办法获取参数,我也可以使用 ListAPIView 来获取关注者。
如何解决这个问题并只列出他们的用户名?
任何帮助将不胜感激。
我在此 link 中使用了嵌套关系。 Django Rest Framework Nested Relationships
只为用户的用户名添加了一个新的序列化器,并更改了另一个序列化器。
# serializes only usernames of users
class EachUserSerializer(serializers.ModelSerializer):
username = serializers.CharField(source='user.username')
class Meta:
model = UserProfile
fields = ('username',)
class FollowerSerializer(serializers.ModelSerializer):
followers = EachUserSerializer(many=True, read_only= True)
followings = EachUserSerializer(many=True,read_only=True)
class Meta:
model = UserProfile
fields = ('followers','followings')
输出正是我想要的:
{
"followers": [],
"followings": [
{
"username": "sneijder"
},
{
"username": "drogba"
}
]
}
谢谢你的帮助:)
我想你需要的是嵌套序列化器:
class FollowerSerializer(serializers.ModelSerializer):
username = serializers.CharField(source='user__username')
class Meta:
model = UserProfile
fields = ('username', )
class FollowerSerializer(serializers.ModelSerializer):
followers = FollowerSerializer(many=True, read_only=True)
class Meta:
model = UserProfile
fields = ('followers', )
我正在使用 Django 1.9.1 开发移动应用程序后端我实现了关注者模型,现在我想列出用户的所有关注者,但我目前坚持这样做。我也使用 Django Rest 框架。
这是我的 UserProfile 模型
class UserProfile(models.Model):
# Linking UserProfile to User model.
user = models.OneToOneField(User)
city = models.CharField(null=True, max_length=30, blank=True)
gender = models.CharField(null=True, max_length=10, blank=True) # m for male, f for female
# TODO: Fix the picture later.
# picture = models.ImageField(upload_to='profile_images', blank=True)
age = models.IntegerField(null=True, blank=True)
caption = models.CharField(null=True, max_length=40, blank=True)
following_count = models.IntegerField(default=0)
follower_count = models.IntegerField(default=0)
post_count = models.IntegerField(default=0)
like_count = models.IntegerField(default=0)
date = models.DateTimeField(default=datetime.now(), blank=True)
is_protected = models.BooleanField(default=False)
is_facebook_created_user = models.BooleanField(default=False)
facebook_id = models.CharField(default='', blank=True, max_length=350)
picture_url = models.URLField(blank=True, max_length=100, null=True)
followings = models.ManyToManyField('self', related_name='following', symmetrical=False)
followers = models.ManyToManyField('self', related_name='follower', symmetrical=False)
blocking = models.ManyToManyField('self', related_name='block', symmetrical=False)
blocked_by = models.ManyToManyField('self', related_name='blocked', symmetrical=False)
def block_user(self,username):
other = UserProfile.objects.get(user__username=username)
if not self.is_blocking(username):
self.blocking.add(other)
other.blocked_by.add(self)
return True
else:
return False
def unblock_user(self, username):
other = UserProfile.objects.get(user__username=username)
if self.is_blocking(username):
self.blocking.remove(other)
other.blocked_by.remove(self)
return True
else:
return False
def follow_user(self, username):
other = UserProfile.objects.get(user__username=username)
if not self.is_following(username):
self.followings.add(other)
self.following_count = self.followings.all().count()
self.save()
other.followers.add(self)
other.follower_count = other.followers.all().count()
other.save()
return True
else:
return False
def unfollow_user(self, username):
other = UserProfile.objects.get(user__username=username)
if self.is_following(username):
self.followings.remove(other)
self.following_count = self.followings.all().count()
self.save()
other.followers.remove(self)
other.follower_count = other.followers.all().count()
other.save()
return True
else:
return False
def is_blocking(self,username):
return self.blockings.all().filter(user__username=username).exists()
def is_blocked_by(self,username):
return self.blocked_by.all().filter(user__username=username).exists()
def is_following(self, username): #returns Bool
return self.followings.all().filter(user__username=username).exists()
def is_followed_by(self, username): #returns Bool
return self.followers.all().filter(user__username=username).exists()
def __unicode__(self):
return self.user.username
def get_token(self):
try:
token = Token.objects.get(user_id=self.user_id)
except:
token = 'error'
return token
def get_username(self):
return self.user.username
如您所见,我使用 ManyToManyField 作为关注者。现在我想列出一个用户的关注者,但我不想只列出他们的所有信息,因为这是不必要的。我只想列出他们的用户名,因为不需要完整的信息,这只是一种浪费。
这是我的粉丝视图。
@api_view(['GET'])
def get_followers(request):
username = request.query_params.get('username', None)
if username is not None:
if UserProfile.objects.all().filter(user__username=username).exists():
wanted = UserProfile.objects.get(user__username=username)
followers = wanted.followers.all()
serializer = FollowerSerializer(followers)
return JsonResponse(serializer.data)
else:
return JsonResponse({"result": "user_does_not_exist"})
else:
#TODO: return current user's followers
return JsonResponse({"result": "provide_username"})
我还为用户的关注者添加了一个序列化程序。
class FollowerSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
field = ('followers',)
问题是,它只列出了所有用户信息,没有提供用户名,但它只列出了他们的 ID,我无能为力。
我忘了说我确实考虑过使用 ListAPIView,但我无法通过它获取用户名参数。如果有办法获取参数,我也可以使用 ListAPIView 来获取关注者。
如何解决这个问题并只列出他们的用户名? 任何帮助将不胜感激。
我在此 link 中使用了嵌套关系。 Django Rest Framework Nested Relationships
只为用户的用户名添加了一个新的序列化器,并更改了另一个序列化器。
# serializes only usernames of users
class EachUserSerializer(serializers.ModelSerializer):
username = serializers.CharField(source='user.username')
class Meta:
model = UserProfile
fields = ('username',)
class FollowerSerializer(serializers.ModelSerializer):
followers = EachUserSerializer(many=True, read_only= True)
followings = EachUserSerializer(many=True,read_only=True)
class Meta:
model = UserProfile
fields = ('followers','followings')
输出正是我想要的:
{
"followers": [],
"followings": [
{
"username": "sneijder"
},
{
"username": "drogba"
}
]
}
谢谢你的帮助:)
我想你需要的是嵌套序列化器:
class FollowerSerializer(serializers.ModelSerializer):
username = serializers.CharField(source='user__username')
class Meta:
model = UserProfile
fields = ('username', )
class FollowerSerializer(serializers.ModelSerializer):
followers = FollowerSerializer(many=True, read_only=True)
class Meta:
model = UserProfile
fields = ('followers', )