我在django项目中工作,我需要在按日期排序的同一视图中列出两个不同的模型。为了实现这一点,我使用继承来将它们全部放入通用查询集中。我的模特是:
class Publication(models.model):
title = models.CharField(max_lengh = 200)
pub_date = models.DateTimeField(default = datetime.now)
headline = models.TextField()
class Meta:
abstract = True
@abc.abstractmethod
def say_hello(self):
return
class New(Publication):
author = models.ForeignKey(Author)
source = models.CharField(max_length = 200)
categories = models.ManyToManyField(Category)
url = '/news/'
def say_hello(self):
return "Hello New!!!"
class Opinion(Publication):
writer = models.ForeignKey(Writer)
style = .models.CharField(max_length=3, choices=(('txt', 'Text'), ('glr', 'Galery')))
url = '/opinions/'
def say_hello(self):
return "Hello Opinion!!!"
我正在尝试调用子类方法,同时迭代发布QuerySet,如下所示:
publications = Publications.objects.all().order_by('-pub_date')
for pub in publications:
pub.say_hello()
url = pub.url
问题是我的QuerySet正在返回Publication对象,所以我无法访问子属性和方法,显然我正在处理Publication对象。我不应该将Publication设置为抽象类,避免处理Publication对象的可能性。它们不应该被阻止被实例化吗?是否有任何选项可以在Publication类中执行QuerySet并返回包含子对象的列表?
如果没有。你们怎么会绕过这种情况?我真的可以使用一些技巧。
答案 0 :(得分:1)
听起来使用多表继承和django多态可能是合适的:
多表继承:https://docs.djangoproject.com/en/dev/topics/db/models/#multi-table-inheritance
Django polymorphic:http://django-polymorphic.readthedocs.org/en/latest/
django中的多表继承允许您拥有一个具有基本字段的基本模型/表。然后,您的子类定义扩展字段,这些字段放在它们自己的表中。当您从任何子类获取带有查询集的记录时,您将从基本模型/表和子类模型/表中获取每条记录的信息。
为了使用基本模型的查询集获取记录,并为每个结果获取相应子类的实例,一个选项是django polymorphic。我以前用过它,效果很好。它肯定有其局限性,但我会试一试。
答案 1 :(得分:0)
每个发布实例都应该有一个' new'属性或意见'属性分别指向两个子类中的一个。请注意,每个实例只有一个属性,所以尝试更好...除了访问它们。
答案 2 :(得分:0)
好吧,我将把我的解决方案的代码放在这里,这要归功于@David的答案。
正如大卫所建议的,我使用了django-polymorphic,这非常简单。但事实上,我已经有一个人口密集的数据库,使事情有点复杂。没什么好修的。
我做的第一件事就是使用south
迁移数据库,以便将新字段(polymorphic_ctype
)添加到我的父模型中(没有字段添加到子类中)。
然后,我在终端上的django shell模式下使用了以下代码。 (python manage.py shell
)
from jornal.models import Publication, New, Opinion
from django.contrib.contenttypes.models import ContentType
ctype_opinion = ContentType.objects.get(model = 'opinion', app_label = 'jornal')
ctype_new = ContentType.objects.get(model = 'new', app_label = 'jornal')
opinions = Opinion.objects.non_polymorphic().all()
news = New.objects.non_polymorphic().all()
for new in news:
new.polymorphic_ctype = ctype_new
new.save()
for opinion in opinions:
opinion.polymorphic_ctype = ctype_opinion
opinion.save()