Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 按中间模型查询集合顺序__Django_Django Queryset_Manytomanyfield_Django Intermediate Table - Fatal编程技术网

Django 按中间模型查询集合顺序_

Django 按中间模型查询集合顺序_,django,django-queryset,manytomanyfield,django-intermediate-table,Django,Django Queryset,Manytomanyfield,Django Intermediate Table,我正在尝试创建一个中间模型,其中created字段记录以下关系的时间 模型如下: class Profile(models.Model): user = models.OneToOneField(User, related_name='profile') realname = models.CharField(max_length=20, verbose_name='真實姓名', blank=True) nickname = models.CharField(max_le

我正在尝试创建一个中间模型,其中
created
字段记录以下关系的时间

模型如下:

class Profile(models.Model):
    user = models.OneToOneField(User, related_name='profile')
    realname = models.CharField(max_length=20, verbose_name='真實姓名', blank=True)
    nickname = models.CharField(max_length=20, verbose_name='暱稱/顯示名稱')

## the intermediate model is connected through following field  ##
    followings = models.ManyToManyField('self', through='FollowShip',
                                        related_name='followers', symmetrical=False,
                                        through_fields=('profile_from', 'profile_to'))

    total_followers = models.IntegerField(default=0)

    def __str__(self):
        return 'Profile of User:{}'.format(self.user.username)


class FollowShip(models.Model):
    profile_from = models.ForeignKey(Profile, related_name='follow_from_set')
    profile_to = models.ForeignKey(Profile, related_name='follow_to_set')
    created = models.DateField(auto_now_add=True, db_index=True)

    def __str__(self):
        return "{} follows {}".format(self.profile_from, self.profile_to)

    class Meta:
        unique_together = ('profile_from', 'profile_to')
它很好用。但是,当我试图通过
FollowShip
模型的
created
字段访问QuerySet订单时。错误发生了

manage.py shell中

>>> user.profile.followings.order_by('followship__created')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Users/young/Desktop/env/strayvoice/lib/python3.5/site-packages/django/db/models/query.py", line 232, in __repr__
    data = list(self[:REPR_OUTPUT_SIZE + 1])
  File "/Users/young/Desktop/env/strayvoice/lib/python3.5/site-packages/django/db/models/query.py", line 256, in __iter__
    self._fetch_all()
  File "/Users/young/Desktop/env/strayvoice/lib/python3.5/site-packages/django/db/models/query.py", line 1087, in _fetch_all
    self._result_cache = list(self.iterator())
  File "/Users/young/Desktop/env/strayvoice/lib/python3.5/site-packages/django/db/models/query.py", line 54, in __iter__
    results = compiler.execute_sql()
  File "/Users/young/Desktop/env/strayvoice/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 824, in execute_sql
    sql, params = self.as_sql()
  File "/Users/young/Desktop/env/strayvoice/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 369, in as_sql
    extra_select, order_by, group_by = self.pre_sql_setup()
  File "/Users/young/Desktop/env/strayvoice/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 47, in pre_sql_setup
    order_by = self.get_order_by()
  File "/Users/young/Desktop/env/strayvoice/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 293, in get_order_by
    field, self.query.get_meta(), default_order=asc))
  File "/Users/young/Desktop/env/strayvoice/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 553, in find_ordering_name
    field, targets, alias, joins, path, opts = self._setup_joins(pieces, opts, alias)
  File "/Users/young/Desktop/env/strayvoice/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 586, in _setup_joins
    pieces, opts, alias)
  File "/Users/young/Desktop/env/strayvoice/lib/python3.5/site-packages/django/db/models/sql/query.py", line 1402, in setup_joins
    names, opts, allow_many, fail_on_missing=True)
  File "/Users/young/Desktop/env/strayvoice/lib/python3.5/site-packages/django/db/models/sql/query.py", line 1327, in names_to_path
    "Choices are: %s" % (name, ", ".join(available)))
django.core.exceptions.FieldError: Cannot resolve keyword 'followship' into field. Choices are: follow_from_set, follow_to_set, followers, followings, id, nickname, realname, total_followers, user, user_id

没有任何错误的线索。

使用
p。从集合中跟随。按('created')排序。

user.profile.following
表示
user.profile
遵循的配置文件。
user.profile.followers
指跟随
user.profile
的个人资料
因此
user.profile.followers
user.profile.followers
都将返回
profile
的查询集,它们只能按
profile
的字段排序,例如user、realname、昵称

如果您想查找后面跟着
use.profile
和order\u by
created
的配置文件,您可以使用:

result = []
for profile_id in user.profile.follow_from_set.order_by('created').values('profile_to'):
    result.append(Profile.objects.get(id=profile_id))
如果有以下内容,您可以通过以下方法优化sql:

profile_ids = user.profile.follow_from_set.order_by('created').values('profile_to')
profiles = Profile.objects.filter(id__in=profile_ids)
最后,按照profile_id的顺序重新排列profile

result = []
result_dict = {}
for profile in profiles:
    result_dict[profile.id] = profile
for id in profile_ids:
    result.append(result_dict[id])
return result

也许有很多更好的方法来解决这个问题。有谁能做出更好的解决方案吗?

相同的错误消息。看起来m2m关系指向“自我”,中间模型的行为与指向不同模型的行为不同。请参阅本文的最后一部分。我想我可以像文档中所说的那样查询Person.objects.filter(…group\uu name='The披头士',…membership\uu date\u joined\uu gt=date(1961,1,1))。你的方法行得通。但要做到这一点,我必须多次将点击添加到数据库中,代价是巨大的。queryset
Profile.objects.filter(followers\uu昵称\uu包含=“”)
就像您推荐的那样。在这里,您可能需要类似于
Profile.objects.filter(followers\u from\u set\u created\u lt=datetime.date(2016,1,1))
Profile.objects.filter(followers\u created\u lt=datetime.date(2016,1,1))
(两者都不起作用)似乎访问中介模型的唯一方法就像您通过
follow\u from\u set
follow\u to\u set
所说的那样。使用第二种方法,这是可以接受的。sql是
'选择“myuser\u followship.”从“myuser\u followship”中选择“profile\u to\u id”,其中是“myuser\u followship”。“profile\u FROM\u id”=1个“myuser\u followship”顺序。“创建”ASC LIMIT 21'
选择“myuser\u profile”。“id”,“myuser\u profile”。“user\u id”,“myuser\u profile”,“myuser\u profile”,“myuser\u profile”,“myuser\u profile”,“realname”,“myuser\u profile”,“myuser\u profile”,“myuser\u profile”,“昵称”,“myuser\u pro。“myuser\u profile”中的“total\u followers”和“myuser\u profile”中的“total\u followship”和“myuser\u followship”中的“total\u followship”和“myuser\u profile\u followship”中的“to\u id”选择U0。profile\u FROM\u id”=1)LIMIT 21'
。我不太清楚
LIMIT 21代表什么。
result = []
result_dict = {}
for profile in profiles:
    result_dict[profile.id] = profile
for id in profile_ids:
    result.append(result_dict[id])
return result