首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有比这个更短/更简单的查询吗?

有比这个更短/更简单的查询吗?
EN

Stack Overflow用户
提问于 2020-05-24 17:23:46
回答 2查看 43关注 0票数 0

我有一个非常简单的模型:一个Clip可以有多个AdBase,一个AdBase可以有多个Clip

代码语言:javascript
复制
class AdBase(models.Model):
    title = models.CharField(max_length=200, default=None, null=True,
                             blank=False)

class Clip(models.Model):
    ads = models.ManyToManyField(AdBase, related_name='clips',
                                 through='ClipAd')


class ClipAd(models.Model):
    clip = models.ForeignKey(Clip, on_delete=models.CASCADE,
                             blank=False, null=False)
    ad = models.ForeignKey(AdBase, on_delete=models.CASCADE,
                           blank=False, null=False)
    position = models.IntegerField(default=0, blank=False, null=False)

我希望在Clip类中有一个查询,它返回按position排序的所有剪辑。

我想出了这个:

代码语言:javascript
复制
class Clip(models.Model):
    ads = models.ManyToManyField(AdBase, related_name='clips',
                                 through='ClipAd')
    def ads_by_position(self):
        # there might be a simpler query than this:
        return [a.ad
                for a in ClipAd.objects.filter(clip=self).order_by('position')]

但是我确信使用我的类Clipads属性有一个更简单的语法,但是我没有找到。

你有什么想法(或者这是唯一的解决方案)?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-24 18:30:59

您可以使用prefetch_related来实现此目的。这也会大大减少你的数据库负载。此外,使用自定义managers值得一看。

代码语言:javascript
复制
class ClipManager(models.Manager):
    def get_with_adds():
        return Clip.objects.filter().prefetch_related("ads")


class AdBase(models.Model):
    title = models.CharField(max_length=200, default="")

class Clip(models.Model):
    ads = models.ManyToManyField(AdBase, related_name='clips',
                                 through='ClipAd')
    objects = ClipManager()


class ClipAd(models.Model):
    clip = models.ForeignKey(Clip, on_delete=models.CASCADE)
    ad = models.ForeignKey(AdBase, on_delete=models.CASCADE)
    position = models.IntegerField(default=0)

clips_with_adds = Clip.objects.get_with_adds()
票数 2
EN

Stack Overflow用户

发布于 2020-05-24 17:49:34

您可以直接访问相关的多对多项目:

代码语言:javascript
复制
def ads_by_position(self):
    return self.ads.all().order_by('position')
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61983961

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档