【问题标题】:Converting raw SQL to Django QuerySet API将原始 SQL 转换为 Django QuerySet API
【发布时间】:2014-01-23 07:02:26
【问题描述】:

型号

class Person(models.Model):
    GENDER = (
    ('M','Male'),
    ('F','Female'),
    )
    first_name = models.CharField("First Name", max_length=100)
    last_name = models.CharField("Last Name",max_length=100)
    middle_name = models.CharField("Middle Name", max_length=100, blank=True)
    suffix_name = models.ManyToManyField(SuffixName, verbose_name="Suffix Name",null=True, blank=True) 
    gender = models.CharField(max_length=1, choices=GENDER)
    department = models.ManyToManyField(Department, verbose_name="Department",null=True, blank=True) 

    def __unicode__(self):
        return (u'%s') % (self.last_name.upper() + ', ' + self.first_name + ' ' + self.middle_name)

class Department(models.Model):
    department_desc = models.CharField('Department', max_length=100,unique=True)
    department_acronym = models.CharField('Department Acronym', max_length=20,blank=True,help_text="Add acronym if any, not required")
    location = models.CharField('Location',max_length=100,blank=True)
    localnumber = models.CharField('Local Number',max_length=30,blank=True)
    active = models.BooleanField('Active',default=True)

    def __unicode__(self):
        return self.department_desc

如何将此原始 SQL 转换为 Django 查询?

SELECT pp.first_name, pd.department_desc, pd.localnumber
FROM person_person as pp 
INNER JOIN person_person_department as ppd on pp.id = ppd.person_id
INNER JOIN person_department as pd on pd.id = ppd.department_id 

【问题讨论】:

    标签: django django-queryset mezzanine


    【解决方案1】:

    使用QuerySet.valuesQuerySet.values_list

    Person.objects.values('first_name', 'department__department_desc', 'department__localnumber')
    # -> Returns a ValuesQuerySet that yields dictionaries when iterated.
    
    Person.objects.values_list('first_name', 'department__department_desc', 'department__localnumber')
    # -> Returns a ValuesQuerySet that yields tuples when iterated.
    

    【讨论】:

    • 真是太快了!谢谢!
    【解决方案2】:

    获取Person 将自动获取相关对象,因此您的查询是:

    people = Person.objects.all()
    

    然后,您可以执行以下操作:

    for person in people:
      print('Person: {0}'.format(person.first_name))
      for dept in person.department_set.all():
          print('Desc: {0}, Local Number: {1}'.format(dept.department_desc,
                                                      dept.localnumber))
    

    如果要限制返回值,请使用values_list

    【讨论】:

    • 这不会“自动获取所有相关对象”,并且会为内部循环的每次迭代生成一个额外的查询,除非您使用 select_related 或 prefetch_related。安装 Django 调试工具栏,它会让你看到生成了哪些查询。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-03
    • 2022-08-18
    • 2012-03-08
    • 2019-06-11
    • 2019-08-05
    • 1970-01-01
    • 2011-04-15
    相关资源
    最近更新 更多