在具有递归 m2m 关系的中介 table 中按字段排序查询集
Order queryset by field in intermediary table with recursive m2m relationship
我的 Django 应用程序中有 followers/followees 系统,我想在发生适当的操作时按用户的关注者和关注者按操作时间排序。
我的模特:
class UserFollow(models.Model):
followee = models.ForeignKey('CustomUser', on_delete=models.CASCADE, related_name='follower_set') # The one who is followed
follower = models.ForeignKey('CustomUser', on_delete=models.CASCADE, related_name='followee_set') # The one who followed
timestamp = models.DateTimeField(auto_now_add=True)
class CustomUser(AbstractBaseUser, PermissionsMixin):
# Other fields which don't matter in this question
followers = models.ManyToManyField('self', blank=True, related_name='followees', symmetrical=False, through='UserFollow')
例如我有一个用户,当他们关注这个用户时,我可以按相反的顺序得到他的所有关注者:
followers = user.followers.all()
# returns <QuerySet [<CustomUser: follower1>, <CustomUser: follower2>, ... , <CustomUser: follower{n}>]
下面的问题当然不行:
followers = user.followers.order_by('-userfollow__timestamp')
我可以按正确的顺序获取关注者 pk,然后获取关注者对象:
followers_pk = user.follower_set.values_list('follower', flat=True).order_by('-timestamp')
# returns <QuerySet [n, ... , 3, 2, 1]>
followers = CustomUser.objects.filter(pk__in=followers_pk)
# returns <QuerySet [<CustomUser: follower1>, <CustomUser: follower2>, ... , <CustomUser: follower{n}>]> (user objects in reverse order)
有什么建议或技巧可以实现我想要的吗?
这是一个简化的例子:
class Doctor(...):
patients = models.ManyToMany('Patient', ..., related_name = 'doctors', through = 'Registration')
class Patient(...):
doctors = models.ManyToMany('Doctor', ..., related_name = 'patients', through = 'Registration')
class Registration(...):
patient = models.ForeignKey('Patient', ..., related_name = 'registrations')
doctor = models.ForeignKey('Doctor', ..., related_name = 'registrations')
timestamp = models.DateTime(...)
那么我们可以这样做:
# get a specific doctor:
doctor = Doctor.objects.get(id='<doctor-id>')
# get and order all patients that registered with this doctor by the registration timestamp:
patients = Patient.objects.filter(doctors=doctor).order_by('registrations__timestamp')
在您的示例中,它看起来像:
# the user we want the followers of:
celebrity = CustomUser.objects.get(id='<celebrity-id>')
# their followers ordered by timestamp:
followers = CustomUser.objects.filter(followees=celebrity).order_by('follower_set__timestamp')
我的 Django 应用程序中有 followers/followees 系统,我想在发生适当的操作时按用户的关注者和关注者按操作时间排序。 我的模特:
class UserFollow(models.Model):
followee = models.ForeignKey('CustomUser', on_delete=models.CASCADE, related_name='follower_set') # The one who is followed
follower = models.ForeignKey('CustomUser', on_delete=models.CASCADE, related_name='followee_set') # The one who followed
timestamp = models.DateTimeField(auto_now_add=True)
class CustomUser(AbstractBaseUser, PermissionsMixin):
# Other fields which don't matter in this question
followers = models.ManyToManyField('self', blank=True, related_name='followees', symmetrical=False, through='UserFollow')
例如我有一个用户,当他们关注这个用户时,我可以按相反的顺序得到他的所有关注者:
followers = user.followers.all()
# returns <QuerySet [<CustomUser: follower1>, <CustomUser: follower2>, ... , <CustomUser: follower{n}>]
下面的问题当然不行:
followers = user.followers.order_by('-userfollow__timestamp')
我可以按正确的顺序获取关注者 pk,然后获取关注者对象:
followers_pk = user.follower_set.values_list('follower', flat=True).order_by('-timestamp')
# returns <QuerySet [n, ... , 3, 2, 1]>
followers = CustomUser.objects.filter(pk__in=followers_pk)
# returns <QuerySet [<CustomUser: follower1>, <CustomUser: follower2>, ... , <CustomUser: follower{n}>]> (user objects in reverse order)
有什么建议或技巧可以实现我想要的吗?
这是一个简化的例子:
class Doctor(...):
patients = models.ManyToMany('Patient', ..., related_name = 'doctors', through = 'Registration')
class Patient(...):
doctors = models.ManyToMany('Doctor', ..., related_name = 'patients', through = 'Registration')
class Registration(...):
patient = models.ForeignKey('Patient', ..., related_name = 'registrations')
doctor = models.ForeignKey('Doctor', ..., related_name = 'registrations')
timestamp = models.DateTime(...)
那么我们可以这样做:
# get a specific doctor:
doctor = Doctor.objects.get(id='<doctor-id>')
# get and order all patients that registered with this doctor by the registration timestamp:
patients = Patient.objects.filter(doctors=doctor).order_by('registrations__timestamp')
在您的示例中,它看起来像:
# the user we want the followers of:
celebrity = CustomUser.objects.get(id='<celebrity-id>')
# their followers ordered by timestamp:
followers = CustomUser.objects.filter(followees=celebrity).order_by('follower_set__timestamp')