2011-02-03 41 views
12

我想通过管理界面配置我的一些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_emailintro_text等漂浮在系统周围。

有没有办法阻止管理员用户在这里添加新记录,而不妨碍他们编辑现有记录

我想我可以通过为这个模型编写一个自定义管理模板来做到这一点,但我想知道是否有更好的方法来配置它。

例如,我可以使用class以外的东西吗?

谢谢!

回答

14

请参阅this question on "keep[ing] settings in database",这里的答案似乎是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的应用程序,我上面提到的,因为它不正是你想要的东西 - 提供用户可编辑的设置 - 不做你做任何额外的,不必要的工作。

+0

谢谢。我对django-dbsettings有些小心,因为开发人员在这里发表了评论:http://www.chicagodjango.com/blog/django-settings-database/ – AP257 2011-02-03 17:23:19

+0

听起来像他对django-dbsettings的抱怨不适用在你的情况。您正在定义代码中的所有设置。我肯定会建议不要编写自己的Singleton来处理这个问题。 – 2011-02-03 21:48:45

+0

这是来自开发者的评论,他说他不再那么担心我。事实上,当我尝试安装它时,我开始出现错误'newforms`,提示它已经过时了...会尝试你的替代建议,谢谢! – AP257 2011-02-07 22:58:16

2

只需设置一个GlobalSettings应用程序或其他与键和值字段。

通过不给他们编辑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') 

有这样的应用程序,但我更喜欢看他们,写我自己的。

2

我会带一个页面出来的WordPress和创建模型支持设置。

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) 

然后,你可以将pickle(serialize)对象放到字段中,你就会变得坚实。

建立一个小api,你可以像wordpress和调用一样狡猾。 AdminOptions.get_option(opt_name)

然后,您可以将自定义设置加载到运行时,保持settings.py模块分离,但是相等。写这个的好地方是在__init__.py文件中。

9

我认为你可以做到这一点最简单的方法是使用的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 docs

如果您需要更多的粒度,并将该类设置为模型级别的单例,请参见django-solo。我遇到了很多单例实现。

对于StackedInline,您可以使用MAX_NUM = 1

0

修改@radtek答案,以防止删除,如果只有一个条目是左

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

我有基本相同的问题,因为原来的海报介绍,并且它很容易被覆盖的ModelAdmin类固定。类似这样的东西在admin.py文件轻松地阻止添加一个新的对象,但允许编辑当前之一:

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 

这并不阻止用户张贴的编辑数据的形式,但发生的事情保持在管理员网站中。根据您是否觉得您的需要是必要的,您可以使用最少的编码启用删除和添加记录。

相关问题