我有3张桌子。用户,发布和共享。帖子是包含所有帖子的表格。 Post与Share有一对多的关系。就是说,Share表是一个表,它指示用户共享了哪些帖子。这是表格的结构:
class Post(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
status = models.CharField(max_length=200)
share_count = models.IntegerField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
url = models.CharField(max_length=150)
class Share(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
shared_at = models.DateTimeField(auto_now_add=True)
我想要的是一个查询,该查询获取用户共享的帖子和用户创建的帖子。例如,假设我们有相同的数据:
发布表
id user status share_count created_at url
1 1 hello 32 2017-06-01 hello
2 2 What's up 22 2017-07-01 whats-up
共享表格
post user shared_at
2 2 2017-07-02
我想要一个查询,该查询将获取用户的共享帖子及其帖子。假设我要为用户1这样做。结果应该是帖子1和帖子2,因为该用户发布了帖子1,还共享了用户2的帖子2。这是到目前为止的内容: 从itertools导入链中
user = User.objects.get(pk=1) # pick a user
own_posts = user.post_set.order_by('-created_at')
shared_posts = user.share_set.order_by('-shared_at')
combined = itertools.chain(own_posts, shared_posts)
def get_ts(obj):
try:
return obj.created_at
except AttributeError:
return obj.shared_at
last_5 = sorted(combined, key=get_ts, reverse=True)[:5]
我在执行最后一行后得到此错误:
TypeError:“ NoneType”实例与“ “ NoneType”
我该如何进行这项工作?为什么会出现此错误?
答案 0 :(得分:1)
我认为您使其变得非常复杂。核心问题在这里,您的集合包含两种类型的元素Post
和share
。我真的建议您不要这样做,因为这样做只会使处理起来更加困难。
但是,我们可以构建例如一个查询集,该查询集将返回由用户发布或由该用户共享的帖子。例如:
from django.db.models import Q
from django.db.models.functions import Coalesce
Post.objects.filter(
Q(user=some_user) |
Q(share__user=some_user)
).annotate(
shared_or_created=Coalesce('share__shared_at', 'created_at')
).order_by('-shared_or_created')
因此,现在我们有了由some_user
创建或由some_user
分享的帖子列表。接下来,我们用shared_or_created
字段注释每个帖子,该字段包含共享的时间,或者在不共享(由用户创建)的情况下,包含创建的时间。最后,我们按降序对该属性进行排序。
将其编码为查询的优点在于它是在数据库级别处理的。此外,它仍然是一个查询集,因此您可以在其上添加额外的过滤器,切片等。
答案 1 :(得分:0)
您收到此错误,是因为您在最后一行中尝试基于键get_ts
进行排序,但是(至少)combined
的两个元素的值是None
get_ts
,因此无法比较。