簡體   English   中英

Django模型繼承w / custom inclusion_tags

[英]Django model inheritance w/ custom inclusion_tags

我會盡可能地嘗試簡化這個。 可以說我有以下內容:

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的視圖,並以每種類類型的自定義方式列出每個特定的詳細信息。 我想使用自定義的inclusion_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 %}
...

我用模板標簽去了上面寫的路線。 但是,我不知道在哪里放邏輯來確定人的類型!

我想最終我希望能夠在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM