Django: Wie Feldwert erhalten dynamisch eigene Template-Tags?
-
28-09-2019 - |
Frage
Ich schreibe einen generischen Template-Tag, dass ein Modells des Feldwert dynamisch basierend auf Benutzereingaben in Vorlagendateien zurückkehren konnte. Die Idee folgt, die in dem Buch „Practical Django Projekt 2nd Edition“ erwähnt, aber die Buchversion ist eine Liste von Objekten bekommen, wo ich nur ein Objektwert erhalten möge. Ich mag die Website-Einstellungen (Titel, Untertitel etc.) und übergeben Sie in der Vorlage dynamisch so erhalten, dass ich den Code nicht noch einmal schreiben muß jedes Feld des Wert zu erhalten.
Hier ist, was ich bisher getan hat.
Definieren Sie eine admin.py für das Modell (hier nicht enthalten, da es nicht wichtig ist)
ein Modell definiert:
from django.db import models
from django.contrib.sites.models import Site
class Naming(models.Model):
title = models.CharField(max_length=250)
site_id = models.ForeignKey(Site)
tagline = models.CharField(max_length=250)
description = models.TextField(blank=True)
def __unicode__(self):
return self.title
Definiert eine Template-Tag-Datei, die Kommentarzeile ist, wo ich stecken
from django.db.models import get_model
from django.contrib.sites.models import Site
from django import template
def do_site_att(parser, token):
bits = token.split_contents()
if len(bits) != 5:
raise template.TemplateSyntaxError("'get_site_att' tag takes exactly four arguments")
model_args = bits[1].split('.')
if len(model_args) != 2:
raise template.TemplateSyntaxError("First argument to 'get_site_att' must be an 'application name'.'model name' string.")
model = get_model(*model_args)
if model is None:
raise template.TemplateSyntaxError("'get_site_att' tag got an invalid model: %s." % bits[1])
return ContentNode(model, bits[2], bits[4])
class ContentNode(template.Node):
def __init__(self, model, field, varname):
self.model = model
self.field = field
self.varname = varname
def render(self, context):
current_site = Site.objects.get_current()
try:
var = self.model.objects.get(site_id=current_site.id)
context[self.varname] = var.title #I get stuck here because it not accepts input like var.field (I have extract the field value above)
except:
context[self.varname] = "Value not found"
return ''
register = template.Library()
register.tag('get_site_att', do_site_att)
Die Vorlage Abfrage in base.html:
{% load general_tags %}
{% get_site_att general.Naming title as title %}
<h1 id="branding">{{title}}</h1>
{% get_site_att general.Naming tagline as tagline %}
<h2 id="tagline">{{tagline}}</h2>
Ich habe versucht, alle Möglichkeiten ich denken kann, kann aber einfach nicht funktioniert. Jede Hilfe ist wirklich zu schätzen. Danke.
Lösung
fand ich die Lösung für diese:
zu den kommentierten Zeilen, verwenden Sie diesen Code ein:
var = self.model.objects.get(site_id__exact=current_site.id)
context[self.varname] = var.__dict__[self.field]#this will get the field's value dynamically, which is what I was looking for
Andere Tipps
Der normale Weg in Python ein Attribut, dessen Namen Sie in einer anderen Variable ist die Verwendung getattr
haben zu erhalten.
context[self.varname] = getattr(var, self.field)