2010-11-02 3 views
2

J'écris une étiquette de modèle générique qui pourrait renvoyer la valeur de champ d'un modèle dynamiquement basé sur des entrées d'utilisateur dans des fichiers modèles. L'idée suit celle qui est mentionnée dans le livre "Practical Django Project 2nd Edition", mais la version livre obtient une liste d'objets où je veux obtenir seulement la valeur d'un objet. Je veux obtenir les paramètres du site (titre, slogan, etc.) et transmettre le modèle dynamiquement afin que je n'aie plus à écrire le code pour obtenir la valeur de chaque champ.Django: Comment obtenir dynamiquement la valeur du champ à l'aide de balises de gabarit personnalisées?

Voici ce que j'ai fait jusqu'à présent.

Définir un admin.py pour le modèle (non inclus ici parce qu'il n'a pas d'importance)

défini un modèle:

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 

Définition d'un fichier d'étiquette de modèle, les commentaires ligne est où je suis coincé

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) 

La requête de modèle dans 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> 

J'ai essayé tous les moyens possibles que je peux penser, mais je ne peux pas obtenir cela fonctionne. Toute aide est vraiment appréciée. Merci.

Répondre

4

J'ai trouvé la solution pour cela:

sur les lignes de commentaires, utilisez ce code:

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 
+0

cela pourrait être l'une des solutions possibles, si vous avez d'autres solutions s'il vous plaît suggérer! – duy

+3

ou plus Django-ey, au lieu de ** var .__ dict __ [self.field] ** vous pouvez ** var._meta.get_field (self.field) ** – Anentropic

4

La façon normale en Python pour obtenir un attribut dont le nom que vous avez dans une autre variable est d'utiliser getattr.

context[self.varname] = getattr(var, self.field) 
Questions connexes