Django中related模型的getattr()
我在我的Django项目中有一个叫做people的类:
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 = People.objects.all()
for p in people:
row = ""
for field in p.get_all_fields():
row += str(getattr(p, field.name)) + ','
我遇到了一个错误:'People'对象没有'password'这个属性。显然,它是没有这个属性的,但我该如何使用与'People'相关的外部对象,通过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
1 个回答
0
也许你可以把这个混合类加到你的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可能不太对。这个只是给你一个参考的想法 :).