对相关对象正确使用django的models.Manager
我需要一个包含ForeignKey的Amodel自定义管理器对相关对象正确使用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
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查询和一些注释。这难道不是定制模型管理器的目的吗?列表的想法来源于此: