Django - 如何将查询合并为一个并将其显示在模板中?

Posted

技术标签:

【中文标题】Django - 如何将查询合并为一个并将其显示在模板中?【英文标题】:Django - How to combine queries in to one and display it in the template? 【发布时间】:2013-11-14 04:11:00 【问题描述】:

假设这是一个应用博客的模型:

class Blog(models.Model):
    title = models.CharField(max_length=200)
    pub_date = models.DateTimeField(default=datetime.now)
    creator = models.ForeignKey(User)
    content = BleachField()

这是应用状态的另一个模型:

class Status(models.Model):
    content = BleachField()
    pub_date = models.DateTimeField(default=datetime.now)
    creator = models.ForeignKey(User)

我如何想出这样的东西:

from blog.models import Blog
from status.models import Status

blog = Blog.objecs.all()
status = Status.objects.all()
all = blog | status

并在模板中显示用户的所有更新。

updates = user.all_set.all()

编辑:

所以我可以在模板中做这样的事情:

% for each in all %
    ....
% endfor %

我不想要的是,在主页中,我想以最新的顺序显示所有用户活动的更新,

例如:

'User updated with new status: blah blah'
'User published a new Blog'
'User published a new Blog'

就像在许多其他社交网站中一样。并且不要分别显示它们。同样,在用户的个人资料中,显示该特定用户的所有活动。

【问题讨论】:

你不能肯定地在 SQL 级别组合它们,因为所需的架构投影不同(一个显着的差异,查询的列数不同)。 @StefanoSanfilippo 请查看编辑。 您只是想合并两个查询集吗? ***.com/questions/431628/… 如果你想要一个活动提要,你应该研究一个可以完成类似django-activity-stream 的应用程序,因为你需要合并名词(“更新”或“发布”)和演员(“鲍勃” ”或“简”) @TimmyO'Mahony 好的。我认为 django-activity-stream 是我正在寻找的。 Bur 我可以使用 django-activity-stream 过滤,是否仅向关注者显示活动等? 【参考方案1】:

您应该为此使用 django 代理模型,这里是 documentation。

这是一个例子:

class BlogAndStatus(models.Model):
    title = models.CharField(max_length=200)
    pub_date = models.DateField()
    creator = models.ForeignKey(User)
    content = models.TextField()
    is_blog = models.BooleanField(default=False)
    is_status = models.BooleanField(default=False)


class BlogManager(models.Manager):
    def get_query_set(self):
        return super(BlogManager, self).get_query_set().filter(is_status=True)


class Blog(BlogAndStatus):
    objects = BlogManager()

    class Meta:
        proxy = True

    def save(self, *args, **kwargs):
        self.is_blog = True
        return super(Blog, self).save(*args, **kwargs)


class StatusManager(models.Manager):
    def get_query_set(self):
        return super(StatusManager, self).get_query_set().filter(is_blog=True)


class Status(BlogAndStatus):
    objects = StatusManager()

    class Meta:
        proxy = True

    def save(self, *args, **kwargs):
        self.is_status = True
        return super(Status, self).save(*args, **kwargs)

您可以通过以下方式获取所有对象:

BlogAndStatus.objects.all()

或者,使用管理器,只是状态:

Status.objects.all()

您可以在 forms.py 中使用常规模型表单,只需确保将字段“is_blog”或“is_status”设置为 True。博客示例:

class BlogForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(BlogForm, self).__init__(*args, **kwargs)
        self.initial['is_blog'] = True

    class Meta:
        model = Blog
        fields = ('title', 'content', 'is_blog')
        widget = 'is_blog': forms.HiddenInput()

【讨论】:

博客、状态或两者的表单? 两种不同的形式。 我用一个小例子更新了答案。如果您认为我已经回答了您的第一个问题,请将答案标记为已接受。【参考方案2】:

我不知道你为什么有这么奇怪的模型;但你能做的最好的就是:

from django.shortcuts import render

def foo(request):
   photo = Photo.objects.filter(creator=request.user)
   status = Status.objects.filter(creator=request.user)
   context = 'photo': photo, 'status': status
   return render(request, 'template.html', context)

然后在你的模板中:

<h4>Photos:</h4>
  <ul>
  % for p in photo %
     <li> p </li>
  % endfor %
  </ul>
<h4>Status:</h4>
  <ul>
  % for s in status %
     <li> s </li>
  % endfor %
  </ul>

【讨论】:

是的,我可以这样做。但我不想单独显示它们。我想根据最新活动显示它们。请检查编辑。

以上是关于Django - 如何将查询合并为一个并将其显示在模板中?的主要内容,如果未能解决你的问题,请参考以下文章

Django:如何从两个模型中获取数据并将其显示在模板中?

如何合并两个查询集并在 django 中创建新的查询集

如何将查询结果转换为字符串并将其插入表行

如何修改查询集并将其保存为新对象?

Qt:如何将 2 个 QQuickItems 合并为一个,然后将其保存为 png

Flutter:使用Dart合并两个图像并将其存储为单个图像