34π
You can override save
method to control a number of instances:
class JuicerBaseSettings(models.Model):
def save(self, *args, **kwargs):
if not self.pk and JuicerBaseSettings.objects.exists():
# if you'll not check for self.pk
# then error will also be raised in the update of exists model
raise ValidationError('There is can be only one JuicerBaseSettings instance')
return super(JuicerBaseSettings, self).save(*args, **kwargs)
12π
Either you can override save and create a class function JuicerBaseSettings.object()
class JuicerBaseSettings(models.Model):
@classmethod
def object(cls):
return cls._default_manager.all().first() # Since only one item
def save(self, *args, **kwargs):
self.pk = self.id = 1
return super().save(*args, **kwargs)
============= OR =============
Simply, Use django_solo
.
https://github.com/lazybird/django-solo
Snippet Courtsy: django-solo-documentation.
# models.py
from django.db import models
from solo.models import SingletonModel
class SiteConfiguration(SingletonModel):
site_name = models.CharField(max_length=255, default='Site Name')
maintenance_mode = models.BooleanField(default=False)
def __unicode__(self):
return u"Site Configuration"
class Meta:
verbose_name = "Site Configuration"
# admin.py
from django.contrib import admin
from solo.admin import SingletonModelAdmin
from config.models import SiteConfiguration
admin.site.register(SiteConfiguration, SingletonModelAdmin)
# There is only one item in the table, you can get it this way:
from .models import SiteConfiguration
config = SiteConfiguration.objects.get()
# get_solo will create the item if it does not already exist
config = SiteConfiguration.get_solo()
- [Django]-A real example of URL Namespace
- [Django]-Django Nested Inline Formsets to Populate Multilevel Nested Form
- [Django]-Sending post data from angularjs to django as JSON and not as raw content
8π
If your model is used in django-admin only, you additionally can set dynamic add permission for your model:
# some imports here
from django.contrib import admin
from myapp import models
@admin.register(models.ExampleModel)
class ExampleModelAdmin(admin.ModelAdmin):
# some code...
def has_add_permission(self, request):
# check if generally has add permission
retVal = super().has_add_permission(request)
# set add permission to False, if object already exists
if retVal and models.ExampleModel.objects.exists():
retVal = False
return retVal
- [Django]-How do I send empty response in Django without templates
- [Django]-Generating PDFs from SVG input
- [Django]-What is the difference between static files and media files in Django?
3π
i am not an expert but i guess you can overwrite the modelβs save() method so that it will check if there has already been a instance , if so the save() method will just return , otherwise it will call the super().save()
- [Django]-Override django's model delete method for bulk deletion
- [Django]-How can I serialize a queryset from an unrelated model as a nested serializer?
- [Django]-RuntimeWarning: DateTimeField received a naive datetime
3π
You could use a pre_save signal
@receiver(pre_save, sender=JuicerBaseSettings)
def check_no_conflicting_juicer(sender, instance, *args, **kwargs):
# If another JuicerBaseSettings object exists a ValidationError will be raised
if JuicerBaseSettings.objects.exclude(pk=instance.pk).exists():
raise ValidationError('A JuiceBaseSettings object already exists')
- [Django]-Django: Using an F expression for a text field in an update call
- [Django]-Is there a way to loop over two lists simultaneously in django?
- [Django]-Django: Filter a Queryset made of unions not working
1π
Iβm a bit late to the party but if you want to ensure that only one instance of an object is created, an alternative solution to modifying a models save() function would be to always specify an ID of 1 when creating an instance β that way, if an instance already exists, an integrity error will be raised.
e.g.
JuicerBaseSettings.objects.create(id=1)
instead of:
JuicerBaseSettings.objects.create()
Itβs not as clean of a solution as modifying the save function but it still does the trick.
- [Django]-Sending post data from angularjs to django as JSON and not as raw content
- [Django]-How can I use Bootstrap with Django?
- [Django]-How to serve django media files via nginx ?
1π
I did something like this in my admin so that I wonβt ever go to original add_new
view at all unless thereβs no object already present:
def add_view(self, request, form_url='', extra_context=None):
obj = MyModel.objects.all().first()
if obj:
return self.change_view(request, object_id=str(obj.id) if obj else None)
else:
return super(type(self), self).add_view(request, form_url, extra_context)
def changelist_view(self, request, extra_context=None):
return self.add_view(request)
Works only when saving from admin
- [Django]-Get class name of django model
- [Django]-Django nested transactions β βwith transaction.atomic()β
- [Django]-Auth_user error with Django 1.8 and syncdb / migrate