V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
onice
V2EX  ›  Python

django 的 view 如何携带通用数据?

  •  
  •   onice · 2020-03-18 11:34:31 +08:00 · 1624 次点击
    这是一个创建于 1711 天前的主题,其中的信息可能已经有所发展或是发生改变。

    各位大佬好,请教个 django 问题:

    我有个需求是这样的,站点标题,版权信息等数据我是以配置的方式存到数据库的。

    但是,每一个页面都需要这些配置数据。

    我总不能每一个 view 都去写一遍获取配置信息的逻辑吧。

    于是我就想抽取一个基类,基类里面写获取这些配置信息的逻辑。其他的 view 继承这个基类

    但是问题来了,其他 view 继承后,在 render 的时候,也得写基类获取的变量。

    假如以后我在基类中加了新变量,那么所有子类都得加新变量。有没有办法能够完全解耦呢?

    谢谢大家~

    第 1 条附言  ·  2020-03-22 18:56:44 +08:00
    谢谢大家的解答。
    5 条回复    2020-03-18 13:55:12 +08:00
    xpresslink
        1
    xpresslink  
       2020-03-18 11:56:06 +08:00
    如果都需要做成基类了,你这个需求本身就不应该放在数据库里面,直接用模板的 include 功能就成了。
    {% include 'xxxxx/footer.html' %}
    把信息放在数据库也可以,做了后端 api,从数据库里面取信息加上 cache, 前端页面里面用 ajax 调用直接前端渲染。

    退一万步非要有这个需要,不要做基类,可以把这些信息写成公用 MIXIN,每个 view 多重继承就可以了。
    class SITE_INFO_MIXIN():
    title ='xxxx'
    copyright = 'xxxxx'

    class myview(view, SITE_INFO_MIXIN):
    est
        2
    est  
       2020-03-18 12:00:49 +08:00 via Android
    写一个函数给 context 注入通用数据就行了?感觉没有必要继承类
    HuberyPang
        3
    HuberyPang  
       2020-03-18 12:19:34 +08:00
    也可以自定义模板标签,放到 base.html 里面,然后继承这个 base.html 也很方便
    wuwukai007
        4
    wuwukai007  
       2020-03-18 12:31:19 +08:00
    注册自定义标签
    register=template.Library()

    @register.simple_tag
    def get_category_id():
    #可以用 redis 缓存.
    xxxx return models.Category.objects.all()

    #加载标签,循环取出
    {%load category_tag%}
    {%get_category_id as get_category_id%}
    {%for list in get_category_id%}

    最后做成 base.html 模板。
    banxi1988
        5
    banxi1988  
       2020-03-18 13:55:12 +08:00
    我认为最佳做法 Django 已经给我们演示了.
    即通过配置模板的 context_processors.
    比如 Django 默认模板配置的如下 :

    ```python
    # https://docs.djangoproject.com/en/dev/ref/settings/#templates
    TEMPLATES = [
    {
    "OPTIONS": {

    "context_processors": [
    "django.template.context_processors.debug",
    "django.template.context_processors.request",
    "django.contrib.auth.context_processors.auth",
    "django.template.context_processors.i18n",
    "django.template.context_processors.media",
    "django.template.context_processors.static",
    "django.template.context_processors.tz",
    "django.contrib.messages.context_processors.messages",
    ],
    },
    },

    ```

    这些 processor 其实就是一个函数 .返回你需要的对象即可.
    比如 messages 这个的实现如下:

    ```python
    from django.contrib.messages.api import get_messages
    from django.contrib.messages.constants import DEFAULT_LEVELS


    def messages(request):
    """
    Return a lazy 'messages' context variable as well as
    'DEFAULT_MESSAGE_LEVELS'.
    """
    return {
    'messages': get_messages(request),
    'DEFAULT_MESSAGE_LEVELS': DEFAULT_LEVELS,
    }


    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2514 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 02:34 · PVG 10:34 · LAX 18:34 · JFK 21:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.