Django模型:如何限制模型中只有一个条目?
我想让我的Django全局设置可以通过后台管理界面进行配置。
为此,我决定把这些设置放在数据库字段里,而不是在 settings.py
文件中。
我关心的设置有:
class ManagementEmail(models.Model):
librarian_email = models.EmailField()
intro_text = models.CharField(max_length=1000)
signoff_text = models.CharField(max_length=1000)
这些设置是一次性的全局设置,所以我只希望系统中存在一个 librarian_email
、intro_text
等等。
有没有办法可以防止管理员用户在这里添加新记录,但又不阻止他们编辑现有记录呢?
我想我可以通过为这个模型写一个自定义的后台模板来实现,但我想知道有没有更简单的方法来配置这个。
我可以使用其他的东西,比如说 class
吗?
谢谢!
8 个回答
4
16
我觉得最简单的方法是使用ModelAdmin里的has_add_permissions函数:
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)
你可以把上面的数字设置成你想要的任何数字,具体可以查看django文档。
如果你需要更细致的控制,并且想在模型层面上让这个类成为单例,可以看看django-solo。我还遇到过很多其他的单例实现。
对于StackedInline,你可以使用max_num = 1。
20
请查看这个关于“在数据库中保存设置”的问题,答案似乎是django-dbsettings
更新
我刚想到另一个选项:你可以创建以下模型:
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)
由于有一个OneToOneField
字段,你每个网站只能有一个ManagementEmail记录。然后,只需确保你在使用网站功能,这样你就可以这样获取设置:
from django.contrib.sites.models import Site
managementemail = Site.objects.get_current().managementemail
注意,大家告诉你的都是对的;如果你的目标是存储设置,把它们一个个添加为模型的字段并不是最好的方法。随着时间的推移添加设置会很麻烦:你需要在模型中添加字段,更新数据库结构,还要修改调用这些设置的代码。
所以我建议使用我上面提到的django应用,因为它正好满足你的需求——提供可供用户编辑的设置——而且不需要你做额外的、不必要的工作。