Python 如何在Django Admin中从外键动态访问字段
所以我有这样的模型:Python 如何在Django Admin中从外键动态访问字段,python,django,django-models,django-admin,getattr,Python,Django,Django Models,Django Admin,Getattr,所以我有这样的模型: class Celebrity(models.Model): #30+ fields here ... class HoneyBadger(models.Model): name = models.CharField(max_length=10) celebrity_owner = models.ForeignKey(Celebrity) class HoneyBadger(models.Model): name = models.Cha
class Celebrity(models.Model):
#30+ fields here ...
class HoneyBadger(models.Model):
name = models.CharField(max_length=10)
celebrity_owner = models.ForeignKey(Celebrity)
class HoneyBadger(models.Model):
name = models.CharField(max_length=10)
celebrity_owner = models.ForeignKey(Celebrity)
def owner_birth_date(self):
return self.celebrity_owner.birth_date
#And so on for every other field in celebrity_owner
现在,我希望霍尼獾的管理界面显示该生物的名称加上名人所有者字段
我知道标准建议是这样做:
class Celebrity(models.Model):
#30+ fields here ...
class HoneyBadger(models.Model):
name = models.CharField(max_length=10)
celebrity_owner = models.ForeignKey(Celebrity)
class HoneyBadger(models.Model):
name = models.CharField(max_length=10)
celebrity_owner = models.ForeignKey(Celebrity)
def owner_birth_date(self):
return self.celebrity_owner.birth_date
#And so on for every other field in celebrity_owner
然后在管理中引用这些方法
相反,我想要一种方法来省去我所有的打字
这是我第一次尝试惰性快捷方式:
class HoneyBadger(models.Model):
name = models.CharField(max_length=10)
celebrity_owner = models.ForeignKey(Celebrity)
def __getattr__(self, name):
"""Dynamically make derived fields for celebrity_owner fields so I don't have to type out"""
field_lookup_prefix = 'celebrity_owner_field_'
if name.startswith(field_lookup_prefix):
field_name = name[len(field_lookup_prefix):]
def wrapper(*args, **kwargs):
return getattr(self.celebrity_owner, field_name)
return wrapper
else:
raise AttributeError('%s not found' % name)
当我在shell中运行它时,它确实可以工作,但是Django管理员不喜欢它。我得到这个错误:
ImproperlyConfigured at /admin/tracker/
HoneyBadgerAdmin.list_display[5], 'celebrity_owner_field_birth_date' is not a callable or an attribute of 'HoneyBadgerAdmin' or found in the model 'HoneyBadger'.
有人知道我如何使我的代码与管理员一起工作,或者是否有其他方法可以避免为每个名人字段键入方法?(可能是某种运行时猴子补丁?看起来您想用名称字段扩展名人类?为什么不在HoneyBadger类中继承该类
class HoneyBadger(Celebrity):
name = models.CharField(max_length=10)
(您可能需要先从数据库中删除旧的Honeybager表,然后才能执行此操作。)有两种可能的解决方法来实现您想要的
def celebrity_link(self):
return '<a href="%s">%s</a>' % (reverse('admin:appname_celebrity_change',args=(self.celebrity_owner.id,)), self.celebrity_owner.celeb_name)
celebrity_link.allow_tags = True
celebrity_link.short_description = u'Celebrity'
class HoneyBadgerAdmin(admin.ModelAdmin):
list_display = [..., celebrity_link, ...]
def名人链接(self):
返回“”(反向('admin:appname\u名人\u change',args=(self.名人\u owner.id.)),self.名人\u owner.celeb\u name)
名人\u link.allow\u tags=True
名人\u link.short\u description=u‘名人’
类HoneyBadgerAdmin(admin.ModelAdmin):
列表显示=[…,名人链接,…]
继承是否会生成一个隐式的onetoone字段来链接这两个字段?一个名人可以拥有多个獾,因此这不起作用。不,继承将父类中的所有字段复制到子类中,因此HoneyBadger将在其表中拥有所有名人字段。这就是所谓的“是一个”关系,其中蜜獾是一个名人。如果你想要一个“有一个”关系,其中名人有一个蜜獾,那么你的原始设计将起作用。只需省去HoneyBadger方法,并将其与honey_badger.名人_owner.birthdate一起引用即可。Django将为您查找外键。但我正试图从管理员那里引用这些字段,所以我不能只说honey_badger.名人_owner.birthdate。哦,这是给管理员的。你可能会认为名人所有者生日符号会起作用,但是你需要这个monkeypatch作为你的HoneyBadger管理员模型:如果只是为了显示这些字段,你可以使用uuuu unicode_uuu()方法,我试过了。我认为内联线不适用于外键,只适用于很多外键。(也可能是1到1?@Greg是的,我意识到这个解决方案不起作用,因为内联线的设计是为了向后跟踪关系。所以,如果你做了与所提供的解决方案完全相反的事情;i、 e.制作HoneyBadgerInline和CelebrityAdmin,然后你可以让所有链接的HoneyBadger出现在名人管理页面中。但这正是我们想要的。最好的替代方法是提供一个指向名人对象的链接。我将编辑解决方案以显示这一点。