Louison Diogo
Louison Diogo

Reputation: 73

Django "Singleton model" to store user settings

I am building a web app with Django. I would like to be able to store final user settings for my app. For now I am using a model Settings that contains all what I need for the app.
It seems ok but I don't think that's the right way to do it because I could have a second row in my database and I don't want it.
I though about using a file but it is not as easy to manage as a table in a database.

Could someone help me with that please ?

Thank you ! :)

Louison

Upvotes: 7

Views: 4545

Answers (4)

Radial
Radial

Reputation: 373

I am a little late to the show here, but why not try a post_save signal?

models.py

class AppSettings(models.Model):
    setting_1 = models.IntegerField()
    setting_1 = models.IntegerField()

signals.py

from someapp.models import AppSettings
@receiver(post_save, 
          sender= AppSettings,
          dispatch_uid="delete_any_new_records"
          )

def delete_any_new_records(sender, instance, **kwargs):
    if AppSettings.objects.all().count() > 1:
        instance.delete()

The first record will be allowed, but all subsequent attempts to add new records will be deleted.

Upvotes: 0

ZaherSarieddine
ZaherSarieddine

Reputation: 126

If you are using admin for that then you can create your admin class as you wish and set has add permission to false. and you can override changelist_view to redirect to the the only predefined row as follows:

def changelist_view(self, request, extra_context=None):
    return HttpResponseRedirect(reverse('admin:erpapp_rescompany_change' , kwargs={'object_id': ResCompany.objects.all().first().pk}))

Upvotes: 0

damon
damon

Reputation: 15128

If I understand your question correctly, you're interested in managing settings for your django app through an editable, easy to update interface.

A popular existing approach to this is implemented by django-constance. It can use your database or redis to store the settings, and it makes them editable through the django admin. You can look at the documentation here.

django-constance admin example

Ultimately, the approach of using a database table to store configuration settings is fine. The issue of having one row can feel odd though, so django-constance's approach is to use a key/value design where each individual configuration key has its own row in the table.

Upvotes: 9

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476544

You can mark the user field as unique=True. This is basically what a OneToOneField field [Django-doc] does. This thus means that a user has at most one related record:

from django.conf import settings

class UserSettings(models.Model):
    user = models.OneToOneField(
        settings.USER_MODEL,
        on_delete=models.CASCADE
    )
    # …

If you thus aim to insert a second row for the same user, it will raise an error (given the database enforces such constraint, but nearly all databases do this). Furthermore if you use a form, Django will do such validation as well.

Upvotes: 0

Related Questions