2014-09-12 46 views
0

我有一類人在我的Django項目:Django的GETATTR()相關車型

class People(models.Model): 
    user  = models.OneToOneField(User, unique=True) 
    adress  = models.CharField(max_length=500) 

    def __unicode__(self): 
    return "%s %s" % (self.user.first_name, self.user.last_name) 
    def get_all_fields(self): 
    return self._meta.fields + self.user._meta.fields 

我創建了一個視圖從Django的數據庫模型導出到一個CSV文件。 當然,將相關模型的信息導出是很好的,例如django用戶也是如此。

但是,當我環在我的人民名單與

people = People.objects.all() 

for p in people: 
row = "" 
for field in p.get_all_fields(): 
    row  += str(getattr(p, field.name)) + ',' 

我得到了錯誤:「人」對象有沒有屬性「密碼」 當然還沒有,但我怎麼能使用異物與'人'有關getattr()通知?

編輯

我終於在我的班級使用一些額外的功能寫了一個小的解決方法

class People(models.Model): 
    user  = models.OneToOneField(User, unique=True) 
    adress  = models.CharField(max_length=500) 

    def __unicode__(self): 
     return "%s %s" % (self.user.first_name, self.user.last_name) 

    def get_all_fields(self): 
     return self._meta.fields + self.user._meta.fields 

    def get_attribute(self, field_name): 
     name_list = self.get_field_names() 
     if field_name in name_list: 
     return unicode(getattr(self, field_name)) 
     else: 
     return unicode(getattr(self.user, field_name)) 

    def get_field_names(self): 
     name_list = [] 
     for field in self._meta.fields: 
     name_list.append(field.name) 
     return name_list 
+0

你應該在get_all_fields(self)中返回一個列表,你也應該在你的類中定義你的元數據。 – 2014-09-12 14:19:51

回答

0

也許你可以這樣的mixin添加到您的人物等級:

class GetNestedFieldsMixin(object): 
    link_fields = set((u"ForeignKey", u"OneToOneField")) 

    @classmethod 
    def _get_nested_fields(cls, obj): 
     for field in obj._meta.fields: 
      value = field.value_from_object(obj) 
      is_link = field.get_internal_type() in cls.link_fields 
      if is_link: 
       nested_obj = field.rel.to.objects.get(pk=value) 
       for name, field, value in cls._get_nested_fields(nested_obj): 
        yield name, field, value 
      else: 
       yield obj._meta.object_name, field.name, \ 
        field.value_to_string(obj) 

    def get_nested_fields(self): 
     return self._get_nested_fields(self) 

class People(GetNestedFieldsMixin, models.Model): 
    ... 

for p in people: 
    for model_name, field, value in p.get_nested_fields(): 
     print(model_name, field, value) 

如果人數變多,您應該使用.select_related來避免內部循環中的數據庫查詢。 link_fields可能不正確。這只是給你一個想法:)。

+0

謝謝你的回答。它讓我在編輯中看到了這個想法。不幸的是,它不是非常方便,必須添加到所有可導出的類中,這些類基本上是我的大部分類。 – BlueSapphire 2014-09-18 10:12:56

+0

不是全部,只是您想要開始輸出的那個。它將爲您提供所有與人有關的關係的所有字段名稱和值,而不僅僅是人員和用戶。也許我不明白你的問題。如果您只想打印出額外的用戶屬性,則不需要解決方案,因爲這很簡單。 – ephes 2014-09-18 15:10:56

+0

我正在尋找一個通用函數,它遵循模型上的外鍵關係,以便通過其字段名來創建實例的屬性。因爲我沒有發現我自己實現了一個基本功能。 – BlueSapphire 2014-09-19 09:14:06