【问题标题】:Best practice for Django sites to set up site configuration variables?Django 站点设置站点配置变量的最佳实践?
【发布时间】:2011-06-21 07:39:49
【问题描述】:

全部!我正在写一个 Django 博客网站。

我是 Django 新手。由于 Django 有松耦合的理念,我相信在使用他们的框架时最好遵循他们的信念。

所以我在这里遇到了一个难题:

我想为我的博客设置一些变量,比如博客标题、口号、我写的每个博客首页的摘要最大长度,以及我应该在首页上每页显示多少个博客摘要.

我可以通过在我的 Django 项目中创建一个新应用程序来做到这一点,并为我网站的配置变量创建模型,然后从其他应用程序中读取这些变量,但这种做法显然打破了松散耦合的理念。

我能想到的唯一解决方法是在我的站点 .wsgi 文件中设置环境变量(我使用 Apache 和 mod_wsgi 来提供 Python 脚本)但我认为弄乱环境变量还不够“干净”。

谁能给我一个更好的解决方案?

【问题讨论】:

    标签: django


    【解决方案1】:

    您可以做的第一件事是在项目的设置模块中设置这些变量,许多应用都会这样做:

    # settings
    BLOG_TITLE = 'My title'
    

    然后,一个好的做法是提供设置默认值,因此您的应用应该有一个设置文件

    # blog/settings.py
    from django.conf import settings
    BLOG_TITLE = getattr(settings, 'BLOG_TITLE', 'MY default title')
    
    # Then wherever, views or context processor
    from blog import settings # See how we're not importing project's settings
    
    title = settings.BLOG_TITLE
    

    另一种选择是创建一个包含所有这些变量的“博客”模型,这可能会邀请您让您的应用拥有一个按照 Django sites 绑定的博客

    from django.contrib.sites.models import Site
    class Blog(models.Model):
      site = models.OneToOneField(Site) # Tied up to a Django site
      title = models.CharField(max_length=256)
    

    现在您可以从管理界面更改这些值并在视图或上下文处理器中使用它们

    site = Site.objects.get_current() # Installed Django Sites app and middleware
    blog = site.blog
    print blog.title
    

    【讨论】:

      【解决方案2】:

      您可以在应用文件夹中创建设置或常量文件并使用它。这样,您的所有常量都将绑定到您的应用程序:

      apps/
        blog/
          __init__.py
          models.py
          urls.py
          constants.py # <-- here it is!
      

      文件可能如下所示:

      BLOG_TITLE = 'My super blog'
      # ...
      

      您可以像这样使用游览常量:

      import blog.constants
      # ...
      return render_to_response('index.html', {title: blog.constants.BLOG_TITLE})
      

      在模板中:

      <title>{{ title }}</title>  
      

      【讨论】:

        【解决方案3】:

        在我看来,最好的方法是使用inheritance添加与站点模型相关的模型

        首先将站点 ID 添加到您的 Django 设置文件中

        SITE_ID = 1
        

        现在在应用中创建模型

        from django.db import models
        from django.contrib.sites.models import Site
        
        class Settings(Site):
            field_a = models.CharField(max_length=150, null=True)
            field_b = models.CharField(max_length=150, null=True)
        
            class Meta:
                verbose_name_plural = 'settings'
                db_table = 'core_settings' # core is name of my app
        
            def __str__(self) -> str:
                return 'Settings'
        
        

        然后编辑该应用的apps.py文件

        from django.apps import AppConfig
        from django.db.models.signals import post_migrate
        
        def build_settings(sender, **kwargs):
            from django.contrib.sites.models import Site
            from .models import Settings
            if Settings.objects.count() < 1:
                Settings.objects.create(site_ptr=Site.objects.first())
        
        
        class CoreConfig(AppConfig):
            default_auto_field = 'django.db.models.BigAutoField'
            name = 'project.apps.core'
        
            def ready(self) -> None:
                post_migrate.connect(build_settings, sender=self)
        

        现在每次运行迁移时都会在 core_settings 中自动生成一行,与您的站点模型具有一对一的关系

        现在您可以像这样访问您的设置

        
        Site.objects.get_current().settings.access_id
        

        可选:如果只有一个站点 从管理站点注销站点模型并禁用在管理面板中创建和删除设置模型

        from django.contrib import admin
        from . import models
        from django.contrib.sites.models import Site
        
        
        admin.site.unregister(Site)
        
        @admin.register(models.Settings)
        class SettingAdminModel(admin.ModelAdmin):
            def has_delete_permission(self, request,obj=None) -> bool:
                return False
        
            def has_add_permission(self, request) -> bool:
                return False
        

        【讨论】:

          猜你喜欢
          • 2010-09-26
          • 2016-04-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-10
          • 2010-09-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多