![](/img/trans.png)
[英]Django template filters, tags, simple_tags, and inclusion_tags
[英]Django model inheritance w/ custom inclusion_tags
我会尽可能地尝试简化这个。 可以说我有以下内容:
class Person(models.Model):
name = models.CharField(max_length=255)
def getRealPerson(self):
# is there a better way to do this?
ret = None
try:
ret = self.worker
except:
try:
ret = self.retired
except:
ret = self
return ret
class Worker(Person):
salary = models.IntegerField(default=0)
class Retired(Person):
age = models.IntegerField()
这个例子对我想要的东西并不重要,请跟我一起去。 这样做的目的是让我可以有一个主人员表来引用所有人。
理想情况下,我希望能够调用Person的视图,并以每种类类型的自定义方式列出每个特定的详细信息。 我想使用自定义的inclusion_tag来执行此操作。
{% load people_extras %}
{% for person in people %}
{% show_person person %}
{% endfor %}
from django import template
@register.inclusion_tag('worker.html')
def show_worker(person):
return {'person':person}
@register.inclusion_tag('worker.html')
def show_retired(person):
return {'person':person}
#How do I write this function and use it as the show_person person tag?
from project.app.models import Worker, Retired
def show_person(person):
person = person.getRealPerson():
if isinstance(person, Worker):
return show_worker # yes, this doesn't work.
我不知道如何让它根据人物类型调用正确的模板。
我无法弄清楚如何使用{%ifequal%}模板完成此操作,如下所示:
{% ifequal person.getRealPerson.__class__.__name__ "Worker" %}
{% show_worker %}
...
我用模板标签去了上面写的路线。 但是,我不知道在哪里放逻辑来确定人的类型!
我想最终我希望能够在Person对象上使用通用视图。
如果有更好的方法可以做到这一点,我愿意接受建议,我只是想让它发挥作用。
我已经被困在这里超过一天......真的可以使用推动。
查看此答案 ,了解在Person表上查询后获取正确人员类型子对象的有效方法。
一旦你有了这个工作,你应该能够通过使用多态来消除模板标签中的大部分复杂性。 如果要使用不同的模板显示每个人的类型,请将该模板名称设为模型的类属性,或者甚至根据模型名称创建模板名称(使用person._meta.module_name)。 一个简单的模板标签应该能够覆盖所有情况,甚至不知道存在哪些子类的任何细节。 编辑无法使用inclusion_tag装饰器注册此单个标记,因为您需要动态确定模板名称。 但是使用simple_tag装饰器编写很容易:
@register.simple_tag
def show_person(person):
t = template.loader.select_template(["%s.html" % person._meta.module_name,
"person.html")
return t.render({'person': person})
这将使用worker.html呈现工作者,使用retired.html呈现退休等。如果找不到子类型的特定模板,则它将回退到默认的person.html。
利用Django的contenttypes框架来识别您的模型类型。
请参阅以下片段: 儿童感知模型继承并在评论中使用Carl Meyer的建议(将作业包装在“ if not self.id:
”中)
我使用了一种方法,我现在很快就一起攻击,做了一个非常相似的工作。 我有许多模型继承自主“基础”模型 - 我可以通过一个独特的代码访问我数据库中的所有内容(我们称之为“转码”)。 为了找出父对象的子对象,我做了这样的事情:
def get_child_types(self):
return [ c.__name__.lower() for c in self.__subclasses__() ]
def get_child(self):
for type in self.get_child_types():
try:
o = self.__getattribute__(type)
except:
pass
else:
return o
我知道它很乱,但它工作正常。 我将对象的“类型”存储在父对象模型的非规范化字段中,因此我只需要“找到”它一次 - 这会减少数据库上的命中数和所需的CPU工作量。 然后我只是覆盖save()以在创建时找到对象类型,并将其存储在该字段中。
希望能帮助到你!
将此片段用于getRealPerson()Person模型方法:
def getRealPerson(self):
from django.db.models.fields.related import OneToOneRel
from django.core.exceptions import ObjectDoesNotExist
for related in self._meta.get_all_related_objects():
rel_opts_name = related.get_accessor_name()
if isinstance(related.field.rel, OneToOneRel):
try:
sub_obj = getattr(self, rel_opts_name)
except ObjectDoesNotExist:
pass
else:
return sub_obj
它将返回第一个相关对象(Worker或Retired)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.