GeoDjango:我可以在用户管理员的内联中使用OSMGeoAdmin吗?

时间:2015-08-16 16:24:14

标签: django django-admin openstreetmap geodjango

b: 1 c: 1 l: 8 包含Profile。我在ProfileAdmin中使用过OSMGeoAdmin,这里:

PointField

但无法弄清楚如何在内联中使用它以便在UserAdmin中显示。我目前的设置如下:

class ProfileAdmin(admin.OSMGeoAdmin):
    model = Profile

在这种情况下是否可以使用类OSMGeoAdmin?

2 个答案:

答案 0 :(得分:4)

这是我猜的一个很好的功能。

作为一种解决方法,您可以利用InlineModelAdminModelAdmin非常相似的事实。两者都延伸BaseModelAdmin

继承StackedInlineModelAdmin不应该太多冲突。

唯一的问题是两个__init__()方法都采用2个位置参数,并且在没有参数的情况下调用super().__init__()。因此,无论继承顺序如何,都将失败TypeError: __init__() missing 2 required positional arguments: 'parent_model' and 'admin_site'

幸运的是,InlineModelAdmin.__init__()方法,我们感兴趣的方法,并不是真正的冗长也不复杂(没有太多的super().__init__()级联调用。)

以下是in Django 1.9的内容:

def __init__(self, parent_model, admin_site):
    self.admin_site = admin_site
    self.parent_model = parent_model
    self.opts = self.model._meta
    self.has_registered_model = admin_site.is_registered(self.model)
    super(InlineModelAdmin, self).__init__()
    if self.verbose_name is None:
        self.verbose_name = self.model._meta.verbose_name
    if self.verbose_name_plural is None:
        self.verbose_name_plural = self.model._meta.verbose_name_plural

以下是其父(BaseModelAdmin)看起来像in Django 1.9

的内容
def __init__(self):
    overrides = FORMFIELD_FOR_DBFIELD_DEFAULTS.copy()
    overrides.update(self.formfield_overrides)
    self.formfield_overrides = overrides

现在让我们把它们放在一起:

from django.contrib.admin.options import FORMFIELD_FOR_DBFIELD_DEFAULTS

# User Admin, with Profile attached
class ProfileInline(OSMGeoAdmin, admin.StackedInline):
    model = Profile
    can_delete = False
    verbose_name_plural = 'Profile'  # As only one is displayed in this view

    def __init__(self, parent_model, admin_site):
        self.admin_site = admin_site
        self.parent_model = parent_model
        self.opts = self.model._meta
        self.has_registered_model = admin_site.is_registered(self.model)
        overrides = FORMFIELD_FOR_DBFIELD_DEFAULTS.copy()
        overrides.update(self.formfield_overrides)
        self.formfield_overrides = overrides
        if self.verbose_name is None:
            self.verbose_name = self.model._meta.verbose_name
        if self.verbose_name_plural is None:
            self.verbose_name_plural = self.model._meta.verbose_name_plural

class UserAdmin(UserAdmin):
    inlines = (
        ProfileInline,
    )

admin.site.unregister(User)
admin.site.register(User, UserAdmin)

这不是一个令人满意的解决方案,因为它需要从django复制/粘贴一些代码,这可能与您使用的Django版本不同,并且在升级Django时可能会很难维护。但是它应该可以工作,直到它作为混合或InlineModelAdmin包含在Django中。

注意:上面的代码段取自Django 1.9 ,您应该浏览github标签以找到与您的版本对应的代码段。

答案 1 :(得分:1)

由于Django管理字段使用小部件,因此您可以使用formfield_overrides覆盖为PointField自动设置的小部件。在这种情况下,您可以覆盖所有PointField实例以使用OSMWidget类,如下所示:

from django.contrib.gis.forms.widgets import OSMWidget 

class ProfileInline(admin.StackedInline):
    model = Profile
    can_delete = False
    verbose_name_plural = 'Profile'  # As only one is displayed in this view
    formfield_overrides = {
        PointField: {"widget": OSMWidget},
    }