11

ho implementato gestione autenticazione utilizzando Django autenticazione con il sito predefinito di amministrazione, ma poi ho voluto usare il mio AdminSite di riscrivere alcuni comportamenti:Auto registrare modelli Django autenticazione utilizzando amministratore del sito personalizzato

class OptiAdmin(admin.AdminSite): 
    site_title = "Optimizer site's admin" 
    #...Other stuff here 

quindi registrato i miei modelli :

admin_site = OptiAdmin(name='opti_admin') 
admin.site.register(MyModel, MyModelAdmin) 
#Other stuff here 

ma quando vado al luogo di amministrazione sono in grado di vedere i modelli che ho appena registrata, che suona giusto solo a me, ma mi piacerebbe vedere tutti gli altri modelli applicazioni in questo nuovo sito personalizzato tra cui gli utenti e i gruppi dell'author e io no k ora come farlo automaticamente come fa l'amministratore predefinito, pls help :).

risposta

9
  1. Crea il tuo AdminSite con un semplice override __init__().
  2. Importa il tuo admin in urls.py.

Sostituire l'amministratore di Django e ottenere il comportamento di autodiscover() è possibile con il minimo sforzo. Ecco una struttura di progetto generato nel tipico django-admin startproject project moda:

project/ 
    manage.py 
    project/ 
     __init__.py 
     settings.py 
     urls.py 
     wsgi.py 
     admin.py # CREATE THIS FILE 

progetto/admin.py: (. Credo che abbia più senso per fare questo a livello di progetto)

from django.contrib.admin import * # PART 1 

class MyAdminSite(AdminSite): 
    site_header = "My Site" 

    def __init__(self, *args, **kwargs): 
     super(MyAdminSite, self).__init__(*args, **kwargs) 
     self._registry.update(site._registry) # PART 2 

site = MyAdminSite() 

progetto/urls.py (frammento):

from . import admin # PART 3 

urlpatterns = [ 
    url(r'^admin/', admin.site.urls), 
] 

Parte 1 è semplice Python. Importando tutto da django.contrib.admin nello spazio dei nomi, si comporta come una sostituzione drop-in. Suppongo che tu non debba farlo, ma aiuta a preservare le aspettative. Parte 3, collega semplicemente l'amministratore. La parte 2 è il vero trucco.Come dice documentation, autodiscover() è chiamato a fare il lavoro. Tutto il autodiscover fa passare attraverso INSTALLED_APPS tentando di importare un file chiamato admin.py. L'importazione esegue naturalmente il codice e quel codice sta facendo la stessa cosa che si fa per registrare i modelli (ad esempio per decorator e per esempio per method). Nessuna magia Si non è necessario registrare i modelli con l'amministratore personalizzato (come dice la documentazione).

L'individuazione automatica sembra più intelligente rispetto al suo register_tokwarg. Ciò indica che è possibile chiamare autodiscover() passando il proprio amministratore. No; non ci sono cavi collegati (funzione futura?). L'assegnazione avviene here ed è corretta nell'istanza AdminSite nativa here (o here utilizzando il decoratore). I modelli contribuiti di Django si registrano a quell'istanza, così come tutte le librerie di terze parti. Non è qualcosa a cui aggrapparti.

Ecco il trucco però, _registry è solo una mappatura del dizionario. Permetti a Django di scoprire automaticamente tutte le cose e quindi solo il copia la mappatura. Ecco perché self._registry.update(site._registry) funziona. "self" è l'istanza di AdminSite personalizzata, "site" è l'istanza di Django e puoi registrare i tuoi modelli con entrambi.

(Nota finale:.. Se i modelli sono mancanti, è a causa di ordine di importazione Tutto l'iscrizione al AdminSite di Django deve accadere prima di copiare _registry Registrazione direttamente al vostro amministratore personalizzato è probabilmente la cosa più facile.)

+0

Ho appena provato questo con Django 1.11 con un'istanza AdminSite personalizzata. I modelli registrati prendono tutti i valori predefiniti dal padre AdminSite e non i valori di default rilevanti dell'istanza figlio. Ad esempio, site_title è impostato su un valore diverso nella mia istanza personalizzata e quando si visualizza uno dei modelli che sono stati registrati automaticamente, i valori predefiniti di Django sono visibili solo per tali modelli. I documenti dicono che è necessario registrarsi manualmente quando si utilizza un'istanza personalizzata. https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#django.contrib.admin.autodiscover –

+0

Hai provato il passaggio 'self._registry.update()' dove Django ha auto- registrato/costruito il suo AdminSite e quindi copiare la mappatura? Ciò potrebbe sovrascrivere i valori esistenti, quindi prova a impostare gli attributi AdminSite (come site_title, header, url, ecc.) Dopo quella chiamata in '__init __()'. – JCotton

+0

Sì, ho provato tutto come hai postato. Quindi, se ho capito bene, vuoi che io ridefinisca site_header etc nella funzione __init__ dopo self._registry_update? –

6

I documenti di Django suggeriscono di utilizzare SimpleAdminConfig con un sito di amministrazione personalizzato.

INSTALLED_APPS = (
    ... 
    'django.contrib.admin.apps.SimpleAdminConfig', 
    ... 
) 

che impedisce ai modelli registrati con il default AdminSite.

La documentazione sembrano dare per scontato che si importare i modelli singolarmente e aggiungerli al tuo sito di amministrazione personalizzato:

from django.contrib.auth.models import Group, User 
from django.contrib.auth.admin import GroupAdmin, UserAdmin 

admin_site.register(Group, GroupAdmin) 
admin_site.register(User, UserAdmin) 

Questo sarebbe molto ripetitivo se si dispone di modelli in molte applicazioni. Non offre alcun consiglio su come registrare automaticamente i modelli da tutte le tue app con il tuo sito personalizzato.

Si potrebbe provare patch scimmia admin e sostituire admin.site con il proprio.

from django.contrib import admin 
admin.site = OptiAdmin(name='opti_admin') 

Poi, quando il codice chiama admin.site.register(), sarebbe registrare il modello con il vostro amministratore del sito. Questo codice dovrebbe essere eseguito prima che tutti i modelli fossero registrati. Potresti provare a inserirla nello AppConfig per la tua app e assicurarti che la tua app sia sopra lo django.contrib.admin.

+0

@ Alasdir Thks, proverò questa patch per scimmie più tardi oggi, sembra che possa funzionare. Inoltre, la registrazione manuale farà sicuramente il lavoro ma dovrei registrare tutti i modelli di ogni app che voglio includere – gerosalesc

+0

Sì, la registrazione manuale potrebbe essere molto ripetitiva! – Alasdair

+0

Funziona con me usando 'import django.contrib.admin' ' django.contrib.admin.sites.site = admin_site' 'django.contrib.admin.site = admin_site' – beruic