2015-08-16 69 views
8

Profile zawiera PointField. Użyłem OSMGeoAdmin w ProfileAdmin, tutaj:GeoDjango: Czy mogę używać OSMGeoAdmin w Inline w Admincie użytkownika?

class ProfileAdmin(admin.OSMGeoAdmin): 
    model = Profile 

Ale nie może dowiedzieć się, jak używać go w inline na wystawie w UserAdmin. Obecnie mam tę konfigurację jak poniżej:

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

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

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

Czy w tej sytuacji można korzystać z klasy OSMGeoAdmin?

Odpowiedz

4

Byłaby to dobra funkcja do zgłaszania, jak sądzę.

Jako obejście można wykorzystać fakt, że InlineModelAdmin jest dość podobny do ModelAdmin. Oba rozszerzają BaseModelAdmin.

Dziedziczenie zarówno z StackedInline, jak i ModelAdmin nie powinno kolidować za bardzo.

Jedynym problemem jest to, że metody __init__() przyjmują 2 argumenty pozycyjne i wywołują super().__init__() bez argumentów. Tak więc bez względu na kolejność dziedziczenia, to nie z TypeError: __init__() missing 2 required positional arguments: 'parent_model' and 'admin_site'

szczęście metody InlineModelAdmin.__init__(), jednego jesteśmy zainteresowani, tak naprawdę nie jest gadatliwy, ani skomplikowane (nie za dużo super().__init__() wzywa w kaskadzie).

Oto jak to wygląda 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 

A oto co jego rodzic (BaseModelAdmin) wygląda in Django 1.9

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

Teraz postawmy to wszystko razem:

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) 

To naprawdę nie jest satysfakcjonujące rozwiązanie, ponieważ wymaga skopiowania/wklejenia kodu z django, który może się różnić w używanej wersji Django i może być trudny do utrzymania przy aktualizacji Django. Powinien jednak działać, dopóki nie zostanie włączony do Django jako miksowanie lub jako InlineModelAdmin.

Uwaga: Powyższe fragmenty kodu zostały zaczerpnięte z Django 1,9, należy przeglądać tagów GitHub znaleźć fragmenty odpowiadające swojej wersji.