Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在Django Admin中从外键动态访问字段_Python_Django_Django Models_Django Admin_Getattr - Fatal编程技术网

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表,然后才能执行此操作。)

有两种可能的解决方法来实现您想要的

  • 在HoneyBadger Admin中提供名人对象的链接:

    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):
    列表显示=[…,名人链接,…]
    
  • 下一个解决方案有点复杂,但会完全满足我们的要求:定义自定义管理模板。基本上从django源代码复制变更表单,并添加自定义代码以显示名人信息。看这个


  • 继承是否会生成一个隐式的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出现在名人管理页面中。但这正是我们想要的。最好的替代方法是提供一个指向名人对象的链接。我将编辑解决方案以显示这一点。