Inheriting the Django model w / custom include_tags

I will try to simplify this as much as possible. Suppose I have the following:

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()

The example doesn't really matter for what I want, just come with me here. The purpose of this is that I can have a table with the main character to refer to all people.

Ideally, I want to be able to call the Person view and each of them to specify individual data for each type of class. I would like to use a custom include_tag for this.

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.

I do not know how to make it invoke the correct template based on the type of person.

I could not figure out how to do this using the template, using {% ifequal%} as follows:

{% ifequal person.getRealPerson.__class__.__name__ "Worker" %}
    {% show_worker %}
...

, , templatetags. , , , !

, Person.

, , , .

... .

+5
4

. - Person.

, , . , ( person._meta.module_name). , - , . EDIT include_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 worker.html, a Retired using retired.html .. , person.html.

+5

Django contenttypes framework, .

: ( "if not self.id:" )

+2

, , . , "" - ( " go" ). , - :

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

, , . "type" , "" , . save(), , .

, !

0

Use this snippet for the getRealPerson () Person method:

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

It will return you the first associated object (either Worker or Pennsylvania).

0
source

All Articles