0

我想我已经阅读了大多数“相关/重复”问题(即来自模板标签的冗长遍历字段名称遍历模型,以及一些更多......)

不幸的是,我担心我需要一些手握......因为我是 django n00b 并且似乎无法使其工作。这是我在 html 中想要的结果:

<!-- this in some section of the template -->
First Name : . Joe
Last Name : .. Blogs

<!-- this in another section -->
City:  ....... Xanadu
Country: ..... Mongolia
Occupation: .. Programmer

<!-- this in another section of the template -->
Age: ......... 75 
Height: ...... 180 cm
Eye color:  .. red

我不想只做 4 或 5 个部分和 10 个可能的字段

{% if data.first_name %}
  First Name:  {{ data.first_name }}
{% endif %}

四十次!:-/ ...所以这是(大致)我的尝试:

模型.py

class GenericPerson(models.Model):
    first_name = models.CharField(_('First Name'),
                        max_length = 200, 
                        help_text = _('What is your name?'))

    last_name = models.CharField(_('Last Name'),
                        max_length = 200, 
                        help_text = _('What is your name?'))
    etc, etc ...

    class Meta:
        abstract = True

class Person(GenericPerson):    
    age_in_years = models.PositiveIntegerField(_('Age'), 
                null = True,
                blank = True,
                help_text=_('When was you born?, mate')) 
    location = models.ForeignKey(GeographicalProfile,
                               verbose_name=_('geolocations'),
                               null = True,
                               blank = True)

    height = ... etc, etc.

视图.py

...
try:
   person = Person.objects.filter(pk=product_id)
except Person.DoesNotExist:
    raise Http404

generaldata = person.values('first_name',
                              'last_name',
                              etc, etc,
                              )[0]
localdata = person.values('city',
                              'country',
                              etc, etc
                              )[0]
physicaldata = person.values('age',
                                 'height',
                                 'eye_color',
                                  etc, etc
                                 )[0]
extra_context[data] = generaldata
extra_context[loc] = localdata
extra_context[phys] = physicaldata

return render_to_response(template_name, extra_context ,context_instance=RequestContext(request))

使用该视图,我可以

模板.html

{% for p in phys.items %}
<ul>
  {% if p.1 %}
     <li>{{p.0}} :  {{p.1}}</li>
  {% endif %}
</ul>
{% endfor %}

对于不同的部分。但这会将字段返回为 age_in_years、eye_color(而不是名称)。好的,所以从上面的帖子中我创建了一个自定义模板标签,

from django import template
register = template.Library()

@register.filter
def get_name(object):
    return object._meta.verbose_name # put here whatever you would like to return

register.tag('get_name', get_name)

,将其加载到模板 {% load person_extras %} 中,现在......我已经盲目地尝试在模板中的任何地方使用这个 {{something|get_object_name}} ......但是我没有理解的蛮力给了我:

“str”对象没有属性“_meta”

“列表”对象没有属性“_meta”

“元组”对象没有属性“_meta”

'dict' 对象没有属性 '_meta'

“ValuesQuerySet”对象没有属性“_meta”

那么,我在哪里使用这个模板标签呢?或者我如何修改我的视图以在 for 循环中使用这个模板标签?

谢谢你的洞察力

4

1 回答 1

3

当你调用person = Person.objects.filter(pk=product_id)时会返回一个QuerySet对象People。当您随后values在此查询集上使用它时——用文档的话来说——:

返回一个 ValuesQuerySet — 一个 QuerySet 子类,它在用作可迭代对象而不是模型实例对象时返回字典。

所以基本上,在你的模板中,当你尝试调用你的模板标签时,你试图调用._meta.verbose_name一个字典对象而不是一个Person对象,这是行不通的。

因此,您可以改为将普通查询集传递给模板,然后限制要为每个部分(常规、本地、物理)显示的字段并使用一些模板过滤器来帮助您。所以像:

try:
    people = Person.objects.filter(pk=product_id)
except Person.DoesNotExist:
    raise Http404

extra_context = {
    'people' : people,
    'general_fieldnames' : ['first_name', 'last_name' ...],
    'local_fieldnames' : ['age', 'weight' ...],
    'physical_fieldnames' : ['age', 'height' ...], 
}
return render_to_response(template_name, extra_context      
    ,context_instance=RequestContext(request))

但是有一个问题(如您所知),因为没有简单的方法可以遍历对象的字段或获取它们的详细名称。相反,我们可以遍历我们的physical_fieldnames列表,从对象中获取相应的字段以及使用过滤器的详细名称。

from django import template
register = template.Library()

@register.filter
def get_field_value(obj, field_name):
    return getattr(obj, field_name, None)

@register.filter
def get_verbose_name(obj, field_name):
    return obj._meta.get_field(field_name).verbose_name

register.tag('get_verbose_name', get_verbose_name)
register.tag('get_field_value', get_field_value)

现在在模板中

{% for person in people %}
<h1>General</h1>
<ul>
{% for field_name in general_fieldnames %}
    {{ person|get_verbose_name:field_name }} : {{ person|get_field_value:field_name }}
{% endfor %}
</ul>
{% endfor %}

...
于 2012-08-04T12:18:10.650 回答