首页 文章

Django getattr()用于相关模型

提问于
浏览
0

我的django项目中有一个人员课程:

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()的通知?

EDIT

我终于在课堂上使用了一些额外的函数来编写一个小的解决方法

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

1 回答

  • 0

    也许你可以将这个mixin添加到你的People类:

    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可能不正确 . 它只是给你一个想法:) .

相关问题