2011-02-03 6 views
12

Voglio rendere alcune delle mie impostazioni globali Django configurabili tramite l'interfaccia di amministrazione.Modelli Django: consente una sola entrata in un modello?

A tal fine, ho deciso di impostarli come campi di database anziché in settings.py.

Queste sono le impostazioni che mi interessa:

class ManagementEmail(models.Model): 
    librarian_email = models.EmailField() 
    intro_text = models.CharField(max_length=1000) 
    signoff_text = models.CharField(max_length=1000) 

Si tratta di una tantum impostazioni globali, così ho sempre e solo voglio che ci sia un unico librarian_email, intro_text ecc galleggianti intorno al sistema.

C'è un modo per impedire agli utenti amministratori di aggiungere nuovi record qui, senza impedire loro di modificare il record esistente?

Credo di poterlo fare scrivendo un modello di amministrazione personalizzato per questo modello, ma mi piacerebbe sapere se c'è un modo più ordinato per configurarlo.

Potrei usare qualcosa di diverso da class, ad esempio?

Grazie!

risposta

14

Vedere this question on "keep[ing] settings in database", dove la risposta sembra essere django-dbsettings

Aggiornamento

solo pensato di un'altra opzione: è possibile creare il seguente modello:

from django.contrib.sites.models import Site 

class ManagementEmail(models.Model): 
    site = models.OneToOneField(Site) 
    librarian_email = models.EmailField() 
    intro_text = models.CharField(max_length=1000) 
    signoff_text = models.CharField(max_length=1000) 

A causa del campo OneToOneField, puoi avere solo un record di ManagementEmail per sito. Poi, basta assicurarsi che si sta utilizzando siti e quindi si può tirare le impostazioni così:

from django.contrib.sites.models import Site 
managementemail = Site.objects.get_current().managementemail 

Nota che ciò che tutti gli altri sta dicendo è vero; se il tuo obiettivo è quello di memorizzare le impostazioni, aggiungerle una ad una come campi per un modello non è la migliore implementazione. Aggiungere le impostazioni nel tempo sarà un problema: devi aggiungere il campo al modello, aggiornare la struttura del database e modificare il codice che chiama tale impostazione.

Ecco perché raccomanderei di usare l'app django che ho menzionato sopra, poiché fa esattamente quello che vuoi - fornisci le impostazioni modificabili dall'utente - senza farti fare un lavoro extra, non necessario.

+0

Grazie. Sono un po 'cauto con django-dbsettings, dato il commento dello sviluppatore qui: http://www.chicagodjango.com/blog/django-settings-database/ – AP257

+0

Sembra che le sue lamentele riguardo a django-dbsettings non si applichino nel tuo caso. Stai definendo tutte le impostazioni nel codice. Consiglio vivamente di non scrivere il tuo Singleton per gestirlo. –

+0

E 'il commento del dev che dice che non lo sta più mantenendo e che mi preoccupa. Infatti, quando ho provato ad installarlo, ho iniziato a ricevere errori su 'newforms', suggerendo che è piuttosto obsoleto ... proverò il tuo suggerimento alternativo, grazie! – AP257

2

Basta installare un'app GlobalSettings o qualcosa con un campo Chiave e Valore.

È possibile impedire facilmente agli utenti amministratori di modificare i valori non concedendo loro l'autorizzazione per modificare l'app GlobalSettings.

class GlobalSettingsManager(models.Manager): 
     def get_setting(self, key): 
      try: 
       setting = GlobalSettings.objects.get(key=key) 
      except: 
       raise MyExceptionOrWhatever 
      return setting 

class GlobalSettings(models.Model): 
     key = models.CharField(unique=True, max_length=255) 
     value = models.CharField(max_length=255) 

     objects = GlobalSettingsManager() 

>>> APP_SETTING = GlobalSettings.objects.get_setting('APP_SETTING') 

Ci sono app per questo, ma preferisco guardarle e scrivere le mie.

+0

Sì, preferirei anche qualcosa nel db piuttosto che in un'app. TUTTAVIA: come indicato nella domanda, l'utente amministratore * dovrebbe essere in grado di modificare * i campi esistenti - non è in grado di aggiungere nuovi elementi. qualche idea? – AP257

2

mi piacerebbe prendere una pagina di wordpress e creare un modello quelle impostazioni di supporto.

class Settings(model.models): 
option_name = models.charfield(max_length = 1000) 
option_value = models.charfield(max_length = 25000) 
option_meta = models.charfield(max_length = 1000) 

Quindi puoi semplicemente mettere a picco (serializzare) gli oggetti nei campi e sarai solido.

Costruisci una piccola api e puoi essere furbo come wordpress e chiamare. AdminOptions.get_option(opt_name)

Quindi è possibile caricare le impostazioni personalizzate nel runtime, mantenendo il modulo settings.py separato, ma uguale. Un buon posto per scrivere questo sarebbe in un file __init__.py.

9

Penso che il modo più semplice che si può fare è usare has_add_permissions funzione del ModelAdmin:

class ContactUsAdmin(admin.ModelAdmin): 
    form = ContactUsForm 

    def has_add_permission(self, request): 
     return False if self.model.objects.count() > 0 else super().has_add_permission(request) 

È possibile impostare il precedente per essere qualsiasi numero che ti piace, vedere il django docs.

Se è necessaria una maggiore granularità di quella e si rende la classe un singleton a livello di modello, vedere django-solo. Ci sono anche molte implementazioni singleton che ho trovato.

Per StackedInline, è possibile utilizzare MAX_NUM = 1.

+1

Penso 'return False se self.model.objects.count()> 0 else super(). Has_add_permission (request)' sarebbe meglio rispetto alle regole di gestione dei permessi. –

+0

C'è un errore se si elimina l'ingresso singolo, questo funziona meglio se 'self.model.objects.count()> 0: \t \t \t return false \t \t altro: \t \t \t ritorno true' – paul100

+0

Se restituisce 0, valuterà 'super(). has_add_permission (request)' e restituirà l'errore se non ci sono permessi, suona bene. – radtek

0

Modifica risposta @radtek per evitare la cancellazione se solo una voce è lasciato

class SendgridEmailQuotaAdmin(admin.ModelAdmin): 
    list_display = ('quota','used') 
    def has_add_permission(self, request): 
     return False if self.model.objects.count() > 0 else True 
    def has_delete_permission(self, request, obj=None): 
     return False if self.model.objects.count() <= 1 else True 
    def get_actions(self, request): 
     actions = super(SendgridEmailQuotaAdmin, self).get_actions(request) 
     if(self.model.objects.count() <= 1): 
      del actions['delete_selected'] 
     return actions 
0

ho avuto sostanzialmente lo stesso problema come il manifesto originale descrive, ed è facilmente fissato sovrascrivendo classi ModelAdmin. Qualcosa di simile a questo in un file admin.py impedisce facilmente l'aggiunta di un nuovo oggetto, ma consente la modifica quella attuale:

class TitleAdmin(admin.ModelAdmin): 
def has_delete_permission(self, request, obj=TestModel.title): 
    return False 

def has_add_permission(self, request): 
    return False 

def has_change_permission(self, request, obj=TestModel.title): 
    return True 

Ciò non impedisce a un utente di inviare un modulo che pubblica i dati, ma mantiene le cose accada nel sito di amministrazione. A seconda che tu ritenga che sia necessario o meno per le tue esigenze, puoi abilitare la cancellazione e l'aggiunta di un record con un minimo di codifica.

Problemi correlati