带自定义included_tags的Django模型继承

标签 django inheritance django-models django-templates

我将尝试尽可能简化此操作。可以说我有以下几点:

models.py

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表来引用所有人。

理想情况下,我希望能够调用Person的 View ,并以自定义方式为每个类类型列出每个特定的详细信息。我想使用自定义的include_tag来执行此操作。

people.html
{% load people_extras %}
{% for person in people %}
   {% show_person person %}
{% endfor %}

people_extras.py-templatetags
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 %}
...

我走了上面用templatetags编写的路线。但是,我不知道确定人的类型的逻辑放在哪里!

我认为最终我希望能够在Person对象上也对此使用通用 View 。

如果有更好的方法可以做到这一点,我欢迎您提出建议,我只是想让它正常工作。

我已经在这里呆了一天多了……真的可以使用推送。

最佳答案

在Person表上查询后,请参见this answer以获取正确的Person类型子对象的有效方法。

完成这些工作后,您应该能够通过使用多态性来消除模板标签中的大多数复杂性。如果要使用不同的模板显示每个人员类型,请将该模板名称设置为模型的类属性,或者甚至仅基于模型名称(使用person._meta.module_name)设置模板名称。这样,一个简单的模板标记就应该能够涵盖所有情况,甚至不知道存在哪些子类的任何详细信息。 编辑不能使用included_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渲染一个Worker,使用retired.html渲染一个Retired,等等。如果未找到该子类型的特定模板,它将使用默认的person.html。

关于带自定义included_tags的Django模型继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/943020/

相关文章:

python - 在 Grails 与 Django 中运行 Web 应用程序

django - 在 Django : User model inheritance or use UserProfile? 中扩展用户对象

c++ - 如何解决由继承和嵌套类引起的这种冗余?

python - Django 用户 M2M 关系

django - 属性错误 : type object '_io.StringIO' has no attribute 'StringIO'

Django - 从数据库中删除重复记录

django haystack - 使用通用 View 函数进行搜索

Java包继承,简单查询

c++ - C/C++ - 从封闭类继承的嵌套类

python - Django 保存点回滚捕获完整性错误导致 TransactionManagementError