I want to make some of my Django global settings configurable through the admin interface.
To that end, I've decided to set them as database fields, rather than in settings.py
.
These are the settings I care about:
class ManagementEmail(models.Model):
librarian_email = models.EmailField()
intro_text = models.CharField(max_length=1000)
signoff_text = models.CharField(max_length=1000)
These are one-off global settings, so I only ever want there to be a single librarian_email
, intro_text
etc floating around the system.
Is there a way I can prevent admin users from adding new records here, without preventing them from editing the existing record?
I guess I can do this by writing a custom admin template for this model, but I'd like to know if there's a neater way to configure this.
Could I use something other than class
, for example?
Thanks!
Please see this question on "keep[ing] settings in database", where the answer seems to be django-dbsettings
Just thought of another option: you can create the following model:
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)
Because of the OneToOneField
field, you can only have one ManagementEmail record per site. Then, just make sure you're using sites and then you can pull the settings thusly:
from django.contrib.sites.models import Site
managementemail = Site.objects.get_current().managementemail
Note that what everyone else is telling you is true; if your goal is to store settings, adding them one by one as fields to a model is not the best implementation. Adding settings over time is going to be a headache: you have to add the field to your model, update the database structure, and modify the code that is calling that setting.
That's why I'd recommend using the django app I mentioned above, since it does exactly what you want -- provide for user-editable settings -- without making you do any extra, unnecessary work.
I think the easiest way you can do this is using has_add_permissions function of the 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)
You can set the above to be any number you like, see the django docs.
If you need more granularity than that, and make the class a singleton at the model level, see django-solo. There are many singleton implementations also that I came across.
For StackedInline, you can use max_num = 1.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With