2012-10-03 58 views
0

越來越列名和.get_FOO_display我有以下幾點:通過Django模型循環,默認情況下

# model 

TITLE_CHOICES = (
    ('mr', 'Mr.'), 
    ('ms', 'Ms.'), 
    ('mrs', 'Mrs.'), 
    ('mis', 'Miss.'), 
) 
class Client(models.Model): 
    name_title = models.CharField(max_length=3, choices=TITLE_CHOICES) 
    first_name = models.CharField(max_length=40) 
    last_name = models.CharField(max_length=40) 

# form 
class ClientForm(ModelForm): 
    class Meta: 
     class = Client 

# view 
def client_view(request): 
    client = Client.object.get(id=1) 
    clientForm = ClientForm(instance=client) 
    return render_to_response('client.html',{'client':client, 
              'clientForm':clientForm}, ...) 

# client.html 
... 

我怎麼能同時確保遍歷對象client打印出來的列名和值,如果值是choice它打印出人類可讀的選擇值,而不是存儲的值(get_title_display)?

爲什麼這不是eaiser在Django中做的? (這不是常見的事情要做嗎?)

如果我不能這樣做,我必須靜態通過每列,並使用get_title_display,這意味着模型和模板之間沒有分離,這意味着如果我改變我的模型,我不得不手動更新模板。這是不好的

回答

1

嘗試類似:

# add to your Client model  
def get_fields(self): 
    fields_display = [] 
    for f in Client._meta.fields: 
     name = f.name   
     if len(f.choices) == 0: 
      fields_display.append([name, f.value_to_string(self)]) 
     else: 
      fields_display.append([name, getattr(self,"get_%s_display" % name)()]) 

    return fields_display 

然後可以循環遍歷模板get_fields給定對象

0

如果你想獲得默認get_FOO_display,你必須覆蓋__getattribute__方法。試試這樣的:

class FooModel(models.Model): 
    ... 
    def __getattribute__(self, item): 
     get = lambda i: object.__getattribute__(self, i) 
     name_map = get('_meta')._name_map 

     if item.startswith('_') or name_map.has_key(item): 
      return get(item) 

     else: 
      field = name_map.get(item) 
      if field.choices: 
       return get('get_%s_display' % item)() 

      else: 
       return get(item)