对相关对象正确使用django的models.Manager

对相关对象正确使用django的models.Manager,django,Django,我需要一个包含ForeignKey的Amodel自定义管理器 class AvailableManager(models.Manager): use_for_related_fields = True def sample(self): from django.db import connection cursor = connection.cursor() cursor.execute(""" SELECT * FROM ana

我需要一个包含ForeignKey的Amodel自定义管理器

class AvailableManager(models.Manager):
    use_for_related_fields = True

    def sample(self):
        from django.db import connection
        cursor = connection.cursor()
        cursor.execute(""" SELECT * FROM anapp_amodel """)
        result_list = []
        for row in cursor.fetchall():
            p = self.model(id=row[0])
            result_list.append(p)
        return result_list


class Amodel(models.Model):
    related_model = models.ForeignKey('AnotherModel', unique=True)
    name = models.CharField(max_length=255, blank=True, null=True)

    objects = models.Manager()
    available = AvailableManager()

    def __unicode__(self):
        return 'Amodel related to '+unicode(self.related_model)
使用管理器时,此实现会引发RelatedObjectDoesNotExist异常:

>>> Amodel.available.sample()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File ".../.virtualenvs/venv/lib/python2.7/site-packages/django/db/models/base.py", line 459, in __repr__
    u = six.text_type(self)
  File ".../anapp/models.py", line 32, in __unicode__
    return u'Amodel at '+unicode(self.related_model)
  File ".../.virtualenvs/venv/lib/python2.7/site-packages/django/db/models/fields/related.py", line 578, in __get__
    "%s has no %s." % (self.field.model.__name__, self.field.name)
RelatedObjectDoesNotExist: Amodel has no related_model.
关于相关字段,执行原始sql的正确方法是什么?目标是实现复杂的SQL查询并对结果进行注释

更新:由于行p=self.modelid=row[0],引发RelatedObjectDoesNotExist异常是正常的。用self.model.objects.getid=row[0]替换它以获得一个实例,从而允许解析相关字段,这是否明智呢?

您的示例方法仅使用主键实例化模型,而不使用其他行数据:

p = self.model(id=row[0])
因此,该实例没有为相关的\u model\u id字段获取任何值

至少你应该做:

p = self.model(*row)
但你为什么要这么做?创建单独的管理器方法是可以的,但是用直接数据库查询替换ORM代码——然后返回一个列表,而不是查询集——是一个坏主意,必然会导致意外问题

编辑

这并不是您使用管理器方法的真正方式。Django已经提供了运行SQL查询并返回模型实例的方法:。所以你的方法就变成了:

def sample(self):
    return self.raw(""" SELECT * FROM anapp_amodel """)
而不是:

self.modelid=仅使用id实例化模型的行[0] 或self.model.objects.getid=为每个实例执行SELECT请求的行[0] 我宁愿用整行实例化模型,以便继续注释每个实例:

from django.db import connection


class AvailableManager(models.Manager):
    use_for_related_fields = True

    def sample(self):
        cursor = connection.cursor()
        cursor.execute(""" SELECT *, 'annotation' FROM ... """)
        result_list = []
        for row in cursor.fetchall():
            annotation = row[-1]
            p = self.model(*row[:-1])
            p.annotation = annotation
            result_list.append(p)
        return result_list

谢谢你,丹尼尔,我刚刚想好了。示例代码,特别是SELECT*FROM。。。该部分仅用于说明。我的用例在这里涉及大量SQL查询和一些注释。这难道不是定制模型管理器的目的吗?列表的想法来源于此: