Это может дать вам некоторое представление -
CREATE TABLE #Temp
(
[Rank] [int],
[Player Name] [varchar](128),
[Ranking Points] [int],
[Country] [varchar](128)
)
INSERT INTO #Temp
SELECT 1,'Rafael Nadal',12390,'Spain'
UNION ALL
SELECT 2,'Roger Federer',7965,'Switzerland'
UNION ALL
SELECT 3,'Novak Djokovic',7880,'Serbia'
DECLARE @xml NVARCHAR(MAX)
DECLARE @body NVARCHAR(MAX)
SET @xml = CAST(( SELECT [Rank] AS 'td','',[Player Name] AS 'td','',
[Ranking Points] AS 'td','', Country AS 'td'
FROM #Temp ORDER BY Rank
FOR XML PATH('tr'), ELEMENTS ) AS NVARCHAR(MAX))
SET @body ='<html><body><H3>Tennis Rankings Info</H3>
<table border = 1>
<tr>
<th> Rank </th> <th> Player Name </th> <th> Ranking Points </th> <th> Country </th></tr>'
SET @body = @body + @xml +'</table></body></html>'
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'SQL ALERTING', -- replace with your SQL Database Mail Profile
@body = @body,
@body_format ='HTML',
@recipients = 'bruhaspathy@hotmail.com', -- replace with your email address
@subject = 'E-mail in Tabular Format' ;
DROP TABLE #Temp
См. этот ответ , чтобы узнать об эффективном способе получить подобъект нужного типа человека после запроса к таблице Person.
Как только вы его получите работая, вы сможете устранить большую часть сложности в тегах шаблона с помощью полиморфизма. Если вы хотите отображать каждый тип человека с использованием другого шаблона, сделайте это имя шаблона атрибутом класса модели или даже просто сделайте имя шаблона на основе имени модели (используя person._meta.module_name). Тогда один простой тег шаблона должен иметь возможность охватить все случаи, даже не зная каких-либо подробностей о том, какие подклассы существуют. РЕДАКТИРОВАТЬ Этот единственный тег нельзя зарегистрировать с помощью декоратора 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, Retired с помощью retired.html и т. Д. Если конкретный шаблон для подтипа не найден, он вернется к человеку по умолчанию .html.
Если конкретный шаблон для подтипа не найден, возвращается значение по умолчанию person.html. Если конкретный шаблон для подтипа не найден, возвращается значение по умолчанию person.html.Я использую метод, который я быстро взломал на данный момент, для выполнения очень похожей работы. У меня есть много моделей, унаследованных от основной «базовой» модели - я могу получить доступ ко всему в моей базе данных с помощью уникального кода (мы называем это «кодом перехода»). Чтобы найти потомка родительского объекта, я делаю что-то вроде этого:
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
Я знаю, что это беспорядочно, но работает нормально. Я сохраняю «тип» объекта в денормализованном поле в родительской объектной модели, поэтому мне нужно «найти» его только один раз, что снижает количество обращений к базе данных и необходимую работу процессора. Затем я просто переопределяю save (), чтобы найти тип объекта при создании и сохранить его в этом поле.
Надеюсь, это поможет!
Воспользуйтесь преимуществами Django's структура типов контента для определения типов вашей модели.
См. Этот фрагмент: Наследование модели с учетом детей и используйте предложение Карла Мейера в комментариях (заключите назначение в " , если не self.id:[1117965 provided")
Используйте этот фрагмент для своего метода модели человека getRealPerson ():
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
Он вернет вам первый связанный объект (рабочий или пенсионер).