2011-02-03 8 views
12

Quiero configurar algunos de mis ajustes globales de Django configurables a través de la interfaz de administración.Modelos de Django: ¿solo se permite una entrada en un modelo?

Para tal fin, he decidido establecerlos como campos de base de datos, en lugar de en settings.py.

Estas son las configuraciones que me importa:

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

Estos son de una sola vez la configuración global, por lo que sólo alguna vez quieren que haya un solo librarian_email, etc intro_text flotando en el sistema.

¿Hay alguna manera de evitar que los usuarios administradores agreguen nuevos registros aquí, sin impedirles editar el registro existente?

Supongo que puedo hacer esto escribiendo una plantilla de administrador personalizada para este modelo, pero me gustaría saber si hay una manera más ordenada de configurar esto.

¿Podría utilizar algo distinto de class, por ejemplo?

Gracias!

Respuesta

14

Por favor, vea this question on "keep[ing] settings in database", donde la respuesta parece ser django-dbsettings

actualización

acaba de ocurrir otra opción: se puede crear el siguiente modelo:

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) 

Debido al campo OneToOneField, solo puede tener un registro de ManagementEmail por sitio. A continuación, sólo asegúrese de que está utilizando los sitios y luego se puede tirar la configuración de esta manera:

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

Tenga en cuenta que lo que los demás le está diciendo es cierto; si su objetivo es almacenar configuraciones, agregarlas una por una como campos a un modelo no es la mejor implementación. Agregar configuraciones a lo largo del tiempo va a ser un dolor de cabeza: debe agregar el campo a su modelo, actualizar la estructura de la base de datos y modificar el código que llama a esa configuración.

Es por eso que recomendaría usar la aplicación django que mencioné anteriormente, ya que hace exactamente lo que usted desea, proporcione ajustes editables por el usuario sin hacer ningún trabajo adicional e innecesario.

+0

Gracias. Estoy un poco receloso de django-dbsettings, dado el comentario del desarrollador aquí: http://www.chicagodjango.com/blog/django-settings-database/ – AP257

+0

Parece que sus quejas sobre django-dbsettings no se aplicarían en tu caso. Está definiendo todas las configuraciones en el código. Definitivamente recomendaría no escribir su propio Singleton para manejar esto. –

+0

Es el comentario del desarrollador que dice que ya no lo mantiene, eso me preocupó. De hecho, cuando intenté instalarlo, comencé a recibir errores sobre 'newforms', sugiriendo que estaba bastante desactualizado ... probaré su sugerencia alternativa, ¡gracias! – AP257

2

Simplemente configure una aplicación GlobalSettings o algo así como un campo de clave y valor.

Puede evitar fácilmente que los usuarios administradores cambien los valores al no darles permiso para editar la aplicación 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') 

Existen aplicaciones para esto, pero prefiero mirarlas y escribir las mías.

+0

Sí, también preferiría algo en el db en lugar de una aplicación. SIN EMBARGO: como se indica en la pregunta, el usuario administrador * debe poder editar * los campos existentes, pero no puede agregar nuevos elementos. ¿Alguna idea? – AP257

2

Me gustaría tener una página de WordPress y crear un modelo que admiten configuraciones

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) 

A continuación, puede simplemente encurtir (serializar) objetos en los campos y será sólido.

Crea un poco de API, y puedes ser tan hábil como WordPress y llamar. AdminOptions.get_option(opt_name)

Luego puede simplemente cargar la configuración personalizada en el tiempo de ejecución, manteniendo el módulo settings.py separado, pero igual. Un buen lugar para escribir esto sería en un archivo __init__.py.

9

Creo que la manera más fácil que puede hacerlo es usando has_add_permissions función 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) 

puede establecer el anterior para ser cualquier número que desee, ver el django docs.

Si necesita más granularidad que eso, y hacer de la clase un singleton en el nivel de modelo, consulte django-solo. También hay muchas implementaciones singleton que encontré.

Para StackedInline, puede utilizar MAX_NUM = 1.

+1

Creo que 'return False if self.model.objects.count()> 0 else super(). Has_add_permission (request)' sería mejor respecto a las reglas de administración de permisos. –

+0

Hay un error si se elimina la entrada única, esto funciona mejor si self.model.objects.count '()> 0: \t \t \t return false \t \t otra cosa: \t \t \t retorno true' – paul100

+0

Si devuelve 0, evaluará 'super(). has_add_permission (request)' y devolverá el error si no hay permiso, eso suena bien. – radtek

0

Modificación de respuesta @radtek para evitar la supresión de si una sola entrada se deja

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

que tenía básicamente el mismo problema que el cartel original describe, y ha arreglado fácilmente reemplazando las clases modelAdmin. Algo similar a esto en un archivo admin.py evita fácilmente añadiendo un nuevo objeto, sino que permite editar el actual:

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 

Esto no impide que un usuario publique una forma que edita los datos, pero mantiene las cosas sucedan en el sitio de administración. Dependiendo de si cree que es necesario o no para sus necesidades, puede habilitar la eliminación y la adición de un registro con un mínimo de codificación.

Cuestiones relacionadas