当每个帖子使用 UUID 而不是顺序 ID 时,如何在 Django 中有效地对随机帖子进行采样?

我有一些 ID 是 UUID 的帖子模型。现在我想在我的 post_detail 模板中显示一些用户可能还希望看到的随机帖子提案......


这就是我处理用户可能还希望在views.py中看到的帖子提案的方式:


def post_proposals():

    post_elements = sorted(

        chain(

            Model1.objects.all(),

            Model2.objects.all(),

            Model3.objects.all()

        )

    )

    post_elements_list = list(post_elements) # Conversion to list is requierd by random

    post_proposals = random.sample(post_elements_list)

    return post_proposals



def post_detail(request, pk):

    ...

  args = {

    'post': post,

    'post_proposals': post_proposals(),

  ...

模板.html:


 {% for post_proposal in post_proposals %}

    <h1>{{ post_proposal.title }}</h1>

 {% endfor %}

现在的问题是,据我所知,这会破坏我的数据库性能......一旦我的数据库中存储了很多帖子,查询就会变得庞大。我首先必须获取 3 个模型的所有元素,然后每次向用户显示帖子时从列表中获取 10 个随机条目。


我还发现以下似乎非常有用:


https://elpenia.wordpress.com/2010/05/11/getting-random-objects-from-a-queryset-in-django/


遗憾的是,我无法使用该解决方案,因为我使用的是非顺序字符串的 UUID,而不是使用 ID 时的 int 值。


ABOUTYOU
浏览 108回答 2
2回答

肥皂起泡泡

问题是你有不同的模型,这使得操作非常昂贵。我建议您添加一个新模型,其中您要查询的所有模型都注册为外键或 id/type 对。有了它,您可以绕过设计缺陷,并且仅提取 id:model.objects.all().values_list('id',flat=True)。random.sample 的结果将是 ids,您可以直接使用 id 拉出帖子在新表的 1 和 count() 之间生成一个随机范围,然后通过处理具有相应索引的记录来提取实际帖子。这将需要您添加一个索引字段,因为 id 可能不是连续的(删除和填充)获得 ID 后,您可以使用 model.objects.filter(id__in=post_proposals) 拉取集合并进一步处理--- 编辑示例实现 ---环绕其他模型的模型看起来像这样:class Model1(models.Model):&nbsp; &nbsp;@staticmethod&nbsp; &nbsp;def get_ref_type(): return 0&nbsp; &nbsp;def create(self):&nbsp; &nbsp; &nbsp; super(Model1,self).create()&nbsp; &nbsp; &nbsp; Posts.register(self,Model1.get_ref_type())&nbsp; &nbsp;def delete(self):&nbsp; &nbsp; &nbsp; Posts.un_register(self,Model1.get_ref_type())&nbsp; &nbsp; &nbsp; super(Model1,self).delete()class Posts(models.Model):&nbsp; class Meta:&nbsp;&nbsp; &nbsp; ....&nbsp; #sequential index, this is what you will filter against&nbsp; index&nbsp; &nbsp; = models.IntegerField(default=0)&nbsp; #type of the model you want to query&nbsp; ref_type = models.IntegerField(default =-1)&nbsp; #id of the record in the table defined in the ref_type field&nbsp; ref_id&nbsp; &nbsp;= models.IntegerField(default =-1)&nbsp; @staticmethod&nbsp; def register(f_objRecord,f_intType):&nbsp; &nbsp; &nbsp; l_objWrp = Posts()&nbsp; &nbsp; &nbsp; #a separate table that will be used to hold the free indexes&nbsp; &nbsp; &nbsp; #it will ensure that even when you delete records, there&nbsp; &nbsp; &nbsp; #won't be any holes in the set&nbsp; &nbsp; &nbsp; l_objWrp.index = PostIndex.get_index()&nbsp; &nbsp; &nbsp; l_objWrp.ref_id = f_objRecord.id&nbsp;&nbsp; &nbsp; &nbsp; l_objWrp.ref_type = f_intType&nbsp; &nbsp; &nbsp; l_objWrp.save()&nbsp; @staticmethod&nbsp; def un_register(f_objRecord,f_intType):&nbsp; &nbsp; &nbsp;l_objWrp = Posts.objects.get(ref_type=f_intType,ref_id=f_objRecord.id)&nbsp; &nbsp; &nbsp;PostIndex.free_index(l_objWrp.index)&nbsp; &nbsp; &nbsp;l_objWrp.delete()&nbsp; def get_data(self):&nbsp; &nbsp; &nbsp;l_intRefType = self.ref_type&nbsp; &nbsp; &nbsp;l_intId&nbsp; &nbsp; &nbsp; = self.ref_id&nbsp; &nbsp; &nbsp;l_objRecord = None&nbsp; &nbsp; &nbsp;if l_intRefType == Model1.get_ref_type():&nbsp; &nbsp; &nbsp; &nbsp; l_objRecord = Model1.objects.get(id=l_intId)&nbsp; &nbsp; &nbsp;elif l_intRefType == Model2.get_ref_type():&nbsp; &nbsp; &nbsp; &nbsp;.....&nbsp; &nbsp; &nbsp;if l_objRecord:&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; #pull the data you want&nbsp; &nbsp; &nbsp;else: raise('unknown model type')

米琪卡哇伊

例如,您可以尝试让数据库随机排序然后切片Model1.objects.order_by('?')[:3]`.文档警告说,这order_by可能既昂贵又缓慢,但可能值得测试,看看它在实践中是否给出了可接受的结果。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python