django查询集在select语句中包含更多列

发布于 2024-11-04 23:45:46 字数 4111 浏览 2 评论 0原文

我一直在尝试使用查询集创建向后关系,并且连接工作正常,接受它不包括所选列中的其他连接表。下面是我的模型、查询集和查询。str() 打印

class Main(models.Model):
    slug       = models.SlugField()
    is_active  = models.BooleanField(default=True)
    site       = models.ForeignKey(Site)
    parent     = models.ForeignKey('self', blank=True, null=True, limit_choices_to={'parent' : None})
    class Meta:
        unique_together = (("slug", "parent"))
    def __unicode__(self):
        return self.slug

class MainI18n(models.Model):
    main                = models.ForeignKey(Main)
    language            = models.CharField(max_length=2, choices=settings.LANGUAGES)
    title               = models.CharField(max_length=100)
    label               = models.CharField(max_length=200, blank=True, null=True)
    description         = models.TextField(blank=True, null=True)
    disclaimer          = models.TextField(blank=True, null=True)
    class Meta:
        unique_together = (("language", "main"))
    def __unicode__(self):
        return self.title
class List(models.Model):
    main        = models.ForeignKey(Main)
    slug        = models.SlugField(unique=True)
    is_active   = models.BooleanField(default=True)
    parent      = models.ForeignKey('self', blank=True, null=True)

    def __unicode__(self):
        return self.slug
class ListI18n(models.Model):
    list        = models.ForeignKey(List)
    language    = models.CharField(max_length=2, choices=settings.LANGUAGES)
    title       = models.CharField(max_length=50)
    description = models.TextField()
    class Meta:
        unique_together = (("language", "list"))
    def __unicode__(self):
        return self.title

和我的查询集

Main.objects.select_related('main', 'parent').filter(list__is_active=True, maini18n__language='en', list__listi18n__language='en')

,这就是我的查询打印的内容

'SELECT `category_main`.`id`, `category_main`.`slug`, `category_main`.`is_active`, `category_main`.`site_id`, `category_main`.`parent_id`, T5.`id`, T5.`slug`, T5.`is_active`, T5.`site_id`, T5.`parent_id` FROM `category_main` INNER JOIN `category_maini18n` ON (`category_main`.`id` = `category_maini18n`.`main_id`) INNER JOIN `category_list` ON (`category_main`.`id` = `category_list`.`main_id`) INNER JOIN `category_listi18n` ON (`category_list`.`id` = `category_listi18n`.`list_id`) LEFT OUTER JOIN `category_main` T5 ON (`category_main`.`parent_id` = T5.`id`) WHERE (`category_maini18n`.`language` = en  AND `category_list`.`is_active` = True  AND `category_listi18n`.`language` = en )'

任何人都可以帮助显示列表和 listi18n 中的列吗?我尝试了额外的方法,但它不允许我传递诸如category_list之类的东西。*

感谢

更新

感谢丹尼尔的方法,我设法让它工作,但我必须从ListI18n开始

ListI18n.objects.select_related('list', 'list__main', 'list__main__parent', 'list__main__i18nmain').filter(list__is_active=True, list__main__maini18n__language='en', language='en').query.__str__()

它现在工作完美,但我无法包含 list_main_maini18n,下面是输出查询

'SELECT `category_listi18n`.`id`, `category_listi18n`.`list_id`, `category_listi18n`.`language`, `category_listi18n`.`title`, `category_listi18n`.`description`, `category_list`.`id`, `category_list`.`main_id`, `category_list`.`slug`, `category_list`.`is_active`, `category_list`.`parent_id`, `category_main`.`id`, `category_main`.`slug`, `category_main`.`is_active`, `category_main`.`site_id`, `category_main`.`parent_id`, T5.`id`, T5.`slug`, T5.`is_active`, T5.`site_id`, T5.`parent_id` FROM `category_listi18n` INNER JOIN `category_list` ON (`category_listi18n`.`list_id` = `category_list`.`id`) INNER JOIN `category_main` ON (`category_list`.`main_id` = `category_main`.`id`) INNER JOIN `category_maini18n` ON (`category_main`.`id` = `category_maini18n`.`main_id`) LEFT OUTER JOIN `category_main` T5 ON (`category_main`.`parent_id` = T5.`id`) WHERE (`category_list`.`is_active` = True  AND `category_listi18n`.`language` = en  AND `category_maini18n`.`language` = en )'

知道如何在查询结果中包含 MainI18n 吗?我应该使用 extra 并包含表并在 where 子句中执行关系吗?或者有更好的方法吗?

I been trying to create a backward relation using queryset and the joining is working fine, accept that its not including the other joined table in the selected columns. Below is my models, queryset and query.str() print

class Main(models.Model):
    slug       = models.SlugField()
    is_active  = models.BooleanField(default=True)
    site       = models.ForeignKey(Site)
    parent     = models.ForeignKey('self', blank=True, null=True, limit_choices_to={'parent' : None})
    class Meta:
        unique_together = (("slug", "parent"))
    def __unicode__(self):
        return self.slug

class MainI18n(models.Model):
    main                = models.ForeignKey(Main)
    language            = models.CharField(max_length=2, choices=settings.LANGUAGES)
    title               = models.CharField(max_length=100)
    label               = models.CharField(max_length=200, blank=True, null=True)
    description         = models.TextField(blank=True, null=True)
    disclaimer          = models.TextField(blank=True, null=True)
    class Meta:
        unique_together = (("language", "main"))
    def __unicode__(self):
        return self.title
class List(models.Model):
    main        = models.ForeignKey(Main)
    slug        = models.SlugField(unique=True)
    is_active   = models.BooleanField(default=True)
    parent      = models.ForeignKey('self', blank=True, null=True)

    def __unicode__(self):
        return self.slug
class ListI18n(models.Model):
    list        = models.ForeignKey(List)
    language    = models.CharField(max_length=2, choices=settings.LANGUAGES)
    title       = models.CharField(max_length=50)
    description = models.TextField()
    class Meta:
        unique_together = (("language", "list"))
    def __unicode__(self):
        return self.title

and my queryset is

Main.objects.select_related('main', 'parent').filter(list__is_active=True, maini18n__language='en', list__listi18n__language='en')

and this is what my query is printing

'SELECT `category_main`.`id`, `category_main`.`slug`, `category_main`.`is_active`, `category_main`.`site_id`, `category_main`.`parent_id`, T5.`id`, T5.`slug`, T5.`is_active`, T5.`site_id`, T5.`parent_id` FROM `category_main` INNER JOIN `category_maini18n` ON (`category_main`.`id` = `category_maini18n`.`main_id`) INNER JOIN `category_list` ON (`category_main`.`id` = `category_list`.`main_id`) INNER JOIN `category_listi18n` ON (`category_list`.`id` = `category_listi18n`.`list_id`) LEFT OUTER JOIN `category_main` T5 ON (`category_main`.`parent_id` = T5.`id`) WHERE (`category_maini18n`.`language` = en  AND `category_list`.`is_active` = True  AND `category_listi18n`.`language` = en )'

anyone can help show columns from list and listi18n? I tried extra but It doesn't allow me to pass things like category_list.*

thanks

UPDATE

Thanks for Daniel approach, I managed to get it to work but instead I had to start from ListI18n

ListI18n.objects.select_related('list', 'list__main', 'list__main__parent', 'list__main__i18nmain').filter(list__is_active=True, list__main__maini18n__language='en', language='en').query.__str__()

Its working perfectly now, but I couldn't include list_main_maini18n, below is the output query

'SELECT `category_listi18n`.`id`, `category_listi18n`.`list_id`, `category_listi18n`.`language`, `category_listi18n`.`title`, `category_listi18n`.`description`, `category_list`.`id`, `category_list`.`main_id`, `category_list`.`slug`, `category_list`.`is_active`, `category_list`.`parent_id`, `category_main`.`id`, `category_main`.`slug`, `category_main`.`is_active`, `category_main`.`site_id`, `category_main`.`parent_id`, T5.`id`, T5.`slug`, T5.`is_active`, T5.`site_id`, T5.`parent_id` FROM `category_listi18n` INNER JOIN `category_list` ON (`category_listi18n`.`list_id` = `category_list`.`id`) INNER JOIN `category_main` ON (`category_list`.`main_id` = `category_main`.`id`) INNER JOIN `category_maini18n` ON (`category_main`.`id` = `category_maini18n`.`main_id`) LEFT OUTER JOIN `category_main` T5 ON (`category_main`.`parent_id` = T5.`id`) WHERE (`category_list`.`is_active` = True  AND `category_listi18n`.`language` = en  AND `category_maini18n`.`language` = en )'

Any idea how can I include MainI18n in the query result? should I use extra and include the tables and do the relation in the where clause? or is there a better approach?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

窝囊感情。 2024-11-11 23:45:47

从Main 到List 的关系是向后的ForeignKey(即FK 位于指向Main 的List 上),而select_lated 则不能以这种方式工作。当你仔细想想,这是正确的:每个 Main 有许多 List,因此说“给我这个 Main 的一个 List”是没有意义的,这就是 select_lated 的意思所有关于。

如果您从列表开始,它会起作用:

List.objects.select_related('main__parent').filter(is_active=True, main__maini18n__language='en', listi18n__language='en')

因为这样您只关注转发关系。您可能会发现您可以重新排序视图/模板以通过这种方式使用查询。

The relationship from Main to List is a backwards ForeignKey (ie the FK is on List pointing at Main), and select_related doesn't work that way. When you think about it, this is correct: there are many Lists for each Main, so it doesn't make sense to say "give me the one List for this Main", which is what select_related is all about.

If you started from List, it would work:

List.objects.select_related('main__parent').filter(is_active=True, main__maini18n__language='en', listi18n__language='en')

because that way you're only following forwards relationships. You may find you're able to reorder your views/templates to use the query this way round.

九公里浅绿 2024-11-11 23:45:47

在我看来它实际上正在工作(您的选择语句中的T5)。您始终可以通过 my_obj.parent.is_active 之类的方式访问 django 中相关实例的字段。如果您在将它们包含在第一个查询中之前使用了 select_lated。如果您未在 select_lated 中指定它,则对 my_obj.parent.is_active 的调用将执行额外的数据库查询。

Looks to me it is actually working (T5 in your select statement). You can always access fields from related instances in django via something like my_obj.parent.is_active. If you used select_related before they are included in the first query. If you didn't specify it in select_related a call to my_obj.parent.is_active for example would perform an extra db query.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文