2012-08-04 55 views
0

我想我讀過最的 「關聯/複製」 的問題各地(即verbose from template-tagiterate over field namesiterate through modelsfewmore ...)Django的:循環或迭代的字段,名稱和verbose_name

不幸的是,我很害怕我需要一些手拿着......因爲我是一個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 %} 

四十次! : -/...所以這裏的(大致)我嘗試:

model.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. 

views.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)) 

使用這個觀點,我可以

template.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) 

,加載在模板{%負載person_extras%},現在......我試圖盲目地使用這個{{東西| get_object_name}}無處不在的模板...但我不理解蠻力給我:

「海峽」對象有沒有屬性「_meta」

「名單」對象有沒有屬性「_meta」

'元組'對象沒有att ribute '_meta'

'字典' 對象有沒有屬性 '_meta'

'ValuesQuerySet' 對象有沒有屬性 '_meta'

所以,我在哪裏使用這個模板標籤?或者如何修改我的視圖以在for循環中使用此模板標記?

感謝你的洞察

回答

3

當你調用person = Person.objects.filter(pk=product_id)將返回PeopleQuerySet一個對象。當您隨後使用values這個查詢集它 - 在文檔的話 - :

返回ValuesQuerySet - 一個QuerySet子類作爲可迭代使用時,而不是模型的實例對象,返回字典。

所以基本上,在你的模板,當您試圖打電話給你的模板標籤,你想叫._meta.verbose_name Dictionary對象而不是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 %} 

... 
+0

,謝謝你的明確的解釋。它解決了一個長期扭曲的搜索!我將編輯您的模板代碼,以確保我們在模板中調用的過濾器與上面定義的過濾器名稱相同,並且我們過濾的「對象」是我們循環的過濾器。乾杯 – Massagran 2012-08-04 16:16:05