2015-08-16 12 views
8

Profile contiene un PointField. Ho usato OSMGeoAdmin nel ProfileAdmin, qui:GeoDjango: Posso utilizzare OSMGeoAdmin in un Inline nell'amministratore utente?

class ProfileAdmin(admin.OSMGeoAdmin): 
    model = Profile 

Ma non riesco a capire come usarlo in una linea per la visualizzazione nella UserAdmin. Attualmente dispongo di questo set come riportato di seguito:

# 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) 

È possibile utilizzare la classe OSMGeoAdmin in questa situazione?

risposta

4

Questa sarebbe una buona caratteristica per richiedere di indovinare.

Come soluzione temporanea, è possibile sfruttare il fatto che uno InlineModelAdmin è abbastanza simile a uno ModelAdmin. Entrambi si estendono BaseModelAdmin.

Ereditare sia da StackedInline sia da ModelAdmin non deve interferire troppo.

L'unico problema è che entrambi i metodi __init__() accettano 2 argomenti posizionali e chiamano super().__init__() senza argomenti. Quindi, qualunque sia l'ordine di ereditarietà, fallirà con TypeError: __init__() missing 2 required positional arguments: 'parent_model' and 'admin_site'

Fortunatamente, il metodo InlineModelAdmin.__init__(), quello che ci interessa, non è davvero verbose né complesso (non troppo super().__init__() chiamate in cascata).

Ecco come si presenta 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 

Ed ecco quello che il suo genitore (BaseModelAdmin) assomiglia in Django 1.9

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

È ora di mettere tutto insieme:

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) 

Non è davvero una soluzione soddisfacente in quanto richiede di copiare/incollare del codice da django, che potrebbe essere diverso all'interno della versione di Django che si usa, e potrebbe essere un problema da mantenere durante l'aggiornamento di Django. Tuttavia dovrebbe funzionare fino a quando non è incluso in Django come mix-in o come InlineModelAdmin.

Nota: i frammenti di codice di cui sopra sono tratte da Django 1,9, si dovrebbe passare in rassegna i tag GitHub per trovare i frammenti corrispondenti alla vostra versione.

Problemi correlati