标签: Django

  • Python3 Django admin后台中设置某个字段可以选择显示H5自定义颜色的选项卡

    Python3 Django admin后台中设置某个字段可以选择显示H5自定义颜色的选项卡

    场景需求

    在Django的项目开发中,如何在后台设置将某个字段使用H5的自定义颜色选择器,实现效果如下图所示:

    可以根据HTML5自定义颜色的设置自定义显示。

    这边我们记录一下如何才能实现

    安装Python扩展

    在终端中执行如下命令

    pip install django-colorfield
    python .\manage.py collectstatic

    设置 settings.py

    打开 settings.py ,将 colorfield 添加到 INSTALLED_APPS 配置中

    models.py 中使用

    from django.db import models
    from colorfield.fields import ColorField
    class ComputerRoom(models.Model):
        name = models.CharField(max_length=256,verbose_name = "名称")
        abbr = models.CharField(max_length=128, blank=True, null=True,verbose_name = "缩写")
        type = models.CharField(max_length=256,verbose_name='类型', choices=typeChoices)
        color = ColorField(default='#FF0000',verbose_name='显示颜色')

    然后在Django后台打开对应的模块就可以看到颜色选择器了。

  • Python3 Django 框架中使用脚本预缓存多计算页面

    Python3 Django 框架中使用脚本预缓存多计算页面

    前面几篇文章我们讲述了

    由于我们的数据里已达到百万计,而且页面中有比较多的mysql跨库跨表的计算,在打开页面时会造成时间过长。所以我们需要在Django框架中如何对页面进行预缓存数据。

    本来我们打算使用 request 页面请求的方式,但是项目中需要登录以后才能看到这个页面,所以这条路不考虑。

    但是我们可以将预缓存的数据提前计算好放在Django的缓存中,然后在使用时显示出来。

    注:可以使用文件缓存的方式进行,然后看定期是否自动有新文件生成出来。

    代码实例

    #!/usr/bin/env python
    # coding: utf-8
    ######
    #  调用方法  python .\manage.py flushCaches
    ######
    from django.core.cache import cache
    from scheduling.views import getIndexResult
    import time , datetime , hashlib
    from django.core.management.base import BaseCommand, CommandError
    class Command(BaseCommand):
        def handle(self, *args, **options):
            date =  time.strftime("%Y-%m-%d %H:%M")
            print('开始预缓存首页数据,时间:%s'%date)
            cache_key = hashlib.md5(('index_'+date).encode(encoding='UTF-8')).hexdigest()
            if not cache.get(cache_key) :
                cache.get_or_set(cache_key, getIndexResult(date) ,60*60)

    调用方法

    python .\manage.py flushCaches

    crontab设置

    */1 * * * * cd /data/wwwroot/scheduling/web/ ; /usr/bin/python manage.py flushCaches >> /tmp/flushCache.log 2>&1

    下次我们打开页面时,速度就很快了。

  • Python3 Django框架中如何使用cache缓存代码实例

    Python3 Django框架中如何使用cache缓存代码实例

    场景描述

    在Django开发中,我们在 views.py 里用到了很多的sql查询,很多的跨表跨库显示,而且数据量已达到百万级,为了加快速度显示,这边启用了缓存。

    一开始我们想使用 @cache_page() 来达到缓存的目的,但是这样的缓存没有找到清除缓存的方法。

    所以我们只好使用cache的方式来缓存,这里用时间(年-月-日 时:分)md5后作为缓存的key。

    而且百度一下以后发现,关于django的cache讲述得很少。我们这里做一下简单的笔记。需要说明一下的是 cache.get_or_set ,我一开始以为是如果有这个值就自动获取,但是发现页面任然很慢。所以查了一下官方手册。 cache.get_or_set 手册里面写的是默认是设置新值。大家使用时一定要防止踩这个坑。

    cache.get_or_set(key, default, timeout=DEFAULT_TIMEOUT, version=None)

    If you want to get a key’s value or set a value if the key isn’t in the cache, there is the get_or_set() method. It takes the same parameters as get() but the default is set as the new cache value for that key, rather than simply returned:

    Python3 Django框架中的缓存机制

    views.py 代码实例

    from django.core.cache import cache
    @login_required
    def index( request ):
        if request.GET.get('date_joined_0') is None :
            lastDate = SnmpDiff.objects.values('update_time').filter( type = 'computer_room.snmp_95' ).order_by('-id')[1]
            date_joined_0 =  lastDate['update_time'].strftime("%Y-%m-%d")
            date_joined_1 =  lastDate['update_time'].strftime("%H:%M")
        else :
            date_joined_0 = request.GET.get('date_joined_0').replace('/','-')
            date_joined_1 = request.GET.get('date_joined_1')
        date = date_joined_0 + ' ' + date_joined_1
        cache_key = hashlib.md5(('index_'+date).encode(encoding='UTF-8')).hexdigest()
        # result = cache.get_or_set(cache_key, getIndexResult(date),60*60)
        if not cache.get(cache_key) :
            result = cache.get_or_set(cache_key, getIndexResult(date),60*60)
        else:
            result = cache.get(cache_key)

    现在除了第一次打开慢一点之外,其他时间打开飞快。

  • 如何在Python3 Django 框架中执行自定义python脚本 图文教程

    如何在Python3 Django 框架中执行自定义python脚本 图文教程

    场景需求

    在Django项目开发中,调用一些底层的东西来跑脚本。

    目录结构

    django入门教程 创建项目(Project)和应用(App)

    这里需要自己新建目录,在应用目录中创建 management/commands 目录,我们这里将脚本名称命名为 flushCaches.py

    脚本代码实例

    #!/usr/bin/env python
    # coding: utf-8
    from django.core.management.base import BaseCommand, CommandError
    class Command(BaseCommand):
        def handle(self, *args, **options):
            # do something ....

    调用方法

    python .\manage.py flushCaches

  • linux下 设置 uwsgi 开机自启动

    linux下 设置 uwsgi 开机自启动

    前面我们写了Docker 下使用Centos系统镜像安装 uwsgi 运行 Python3 Django,但是重启docker以后容器中的uwsgi不能自动启动,所以我们这里来讲解一下如何另 uwsgi 开机自启动。

    终端进入Linux启动文件夹

    cd /etc/init.d

    在/etc/init.d/ 文件夹下创建一个shell脚本名为 uwsgi.sh 添加如下内容 :

    #!/bin/bash -e
    /usr/bin/uwsgi --ini /data/wwwroot/traffic_scheduling/web/uwsgi.ini

    修改uwsgi.sh的文件权限

    chmod 755 uwsgi.sh

    添加到开机自动启动

    update-rc.d uwsgi.sh defaults 99
  • Python3 Django框架中的缓存机制

    Python3 Django框架中的缓存机制

    概述:对于中等流量的网站来说,尽可能的减少开销是非常必要的。缓存数据就是为了保存那些需要很多计算资源的结果,这样的话就不必在下次重复消耗计算资源。获取数据的数据的时候就是去缓存中拿,拿到了直接返回,没拿到就去数据库中查询,筛选,然后缓存到数据库, 然后返回给模板。

    Django自带了一个健壮的缓存系统来保存动态页面,避免每次请求都重新计算。

    Django提供了不同级别的缓存策略,可以缓存特定的视图的输出、可以仅仅缓存那些很难计算出来的部分、或者缓存整个网站

    目的:优化数据结构;优化了对数据的查询;筛选,过滤;减少了对磁盘的IO

    官方文档:https://docs.djangoproject.co…

    设置缓存

    通过设置决定把数据缓存在哪里,是数据库中、文件系统中还是内存中

    默认缓存(内存)

    CACHES={
        'default':{
            'BACKEND':'django.core.cache.backends.locmem.LocMemCache',
            'LOCATION': 'unique-snowflake',
            'TIMEOUT':60
        }
    }

    参数TIMEOUT:缓存的默认过期时间,以秒为单位

    • 默认为300秒
    • 设置为None,表示永不过期
    • 设置为0造成缓存立即失效

    文件缓存

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
            'LOCATION': 'c:/foo/bar',
            'TIMEOUT':300,
        }
    }

    数据库缓存

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
            'LOCATION': 'my_cache_table',
            'TIMEOUT': '60',
            'KEY_PREFIX': 'bbs',
            'VERSION': '1',
            'OPTIONS': {
                'MAX_ENTRIES': '300'
            }
        }
    }

    创建缓存表: python manage.py createcachetable

    drf的缓存

    https://github.com/chibisov/drf-extensions

    这是drf的一个扩展,不止增强了缓存还有其他的。

    pip install drf-extensions
    

    缓存viewset中的retrieve和list 方法是很常见的。这就是为什么CacheResponseMixin存在。

    获取数据的才会用到cache

    from rest_framework_extensions.cache.mixins import CacheResponseMixin

    把这个CacheResponseMixin,放在list之前。尽量放在第一个继承的类

    class GoodsListViewSet(CacheResponseMixin,mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    

    设置过期时间

    REST_FRAMEWORK_EXTENSIONS = {
        'DEFAULT_CACHE_RESPONSE_TIMEOUT': 5
    }
    

    根据自己需求加缓存。目前这个缓存使用的是内存。每次系统重启会丢失。

    redis缓存

    官网: http://django-redis-chs.readt…

    redis操作文档:http://redisdoc.com

    默认使用redis中的1数据库,但可以指定使用哪个db

    安装pip install django-redis

    配置

    # ---配置Session和Cache---
    CACHES={
        'default':{
            'BACKEND': 'django_redis.cache.RedisCache',
            'LOCATION':'127.0.0.1:6379/12', # 指定db12
            'TIMEOUT':60,
            'OPTIONS': {
                'CLIENT_CLASS': 'django_redis.client.DefaultClient',  # 指定连接Redis的客户端类
                # 'PASSWORD': 'mysecret',
                 # "SOCKET_CONNECT_TIMEOUT": 5,  # in seconds
                 # "SOCKET_TIMEOUT": 5,  # in seconds
                 # "CONNECTION_POOL_KWARGS": {"max_connections": 100},
                 # "CONNECTION_POOL_CLASS": "myproj.mypool.MyOwnPool",
            }
        }
    }
    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
    # --结束Session和Cache配置
    参数解释
    SOCKET_CONNECT_TIMEOUTsocket 建立连接超时设置
    SOCKET_TIMEOUT连接建立后的读写操作超时设置
    CONNECTION_POOL_KWARGS设置连接池的最大连接数量
    CONNECTION_POOL_CLASS自己的连接池子类

    连接池

    django-redis 使用 redis-py 的连接池接口, 并提供了简单的配置方式. 除此之外, 你可以为 backend 定制化连接池的产生。redis-py 默认不会关闭连接, 尽可能重用连接。

    连接池概念

    为什么使用连接池?首先Redis也是一种数据库,它基于C/S模式,因此如果需要使用必须建立连接,稍微熟悉网络的人应该都清楚地知道为什么需要建立连接,C/S模式本身就是一种远程通信的交互模式,因此Redis服务器可以单独作为一个数据库服务器来独立存在。假设Redis服务器与客户端分处在异地,虽然基于内存的Redis数据库有着超高的性能,但是底层的网络通信却占用了一次数据请求的大量时间,因为每次数据交互都需要先建立连接,假设一次数据交互总共用时30ms,超高性能的Redis数据库处理数据所花的时间可能不到1ms,也即是说前期的连接占用了29ms,连接池则可以实现在客户端建立多个链接并且不释放,当需要使用连接的时候通过一定的算法获取已经建立的连接,使用完了以后则还给连接池,这就免去了数据库连接所占用的时间。

    配置默认连接池

    配置默认连接池很简单, 你只需要在 CACHES 中使用 CONNECTION_POOL_KWARGS 设置连接池的最大连接数量即可

    你可以得知连接池已经打开多少连接:

    from django.core.cache import get_cache
    from django_redis import get_redis_connection
    r = get_redis_connection("default")  # Use the name you have defined for Redis in settings.CACHES
    connection_pool = r.connection_pool
    print("Created connections so far: %d" % connection_pool._created_connections)

    使用自己的连接池子类

    有时你想使用自己的连接池子类. django-redis 提供了 CONNECTION_POOL_CLASS 来配置连接池子类

    myproj/mypool.py

    from redis.connection import ConnectionPool
    class MyOwnPool(ConnectionPool):
        # Just doing nothing, only for example purpose
        pass

    缓存的用法

    单个view缓存

    django.views.decorators.cache.cache_page装饰器用于对视图 views.py 的输出进行缓存

    from django.views.decorators.cache import cache_page
    @cache_page(60 * 2)
    def index(request):
        # return HttpResponse("sunck is a good man")
        return HttpResponse("sunck is a nice man")
    参数:
    timeout : 有效时长  # we've written it as 60 * 15 for the purpose of readability
    cache: 缓存到哪一个库中;很少使用;针对于系统配置了多个缓存
           如: @cache_page(timeout=60, cache='filecache')
    key_prefix: 前缀      

    模板片段缓存

    cache标签: 参数

    • 缓存时间,以秒为单位
    • 给缓存片段起名字
    {#{% load static from staticfiles %}#}
    {% load static %}
    {% load cache %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>主页</title>
    {#    <link rel="stylesheet" type="text/css" href="/static/css/index.css">#}
        <link rel="stylesheet" type="text/css" href="{% static 'css/index.css' %}">
    </head>
    <body>
        <h1>sunck is a nice man</h1>
        {% cache 120 sunck %}
            <h1>nice man</h1>
            <!--<h1>good man</h1>-->
        {% endcache %}
    </body>
    </html>

    原生cache

    from django.core.cache import cache
    查看所有缓存的key: cache.keys('*')
    设置:cache.set(键, 值, 有效时间)
    获取:cache.get(键)
    删除:cache.delete(键)
    清空:cache.clear()
    >>> cache.set_many({'a': 1, 'b': 2, 'c': 3})
    >>> cache.getmany(['a','b','c'])
    {'a': 1, 'b': 2, 'c': 3}
    cache.delete_pattern("foo_*") # 全局通配符
  • Python3 Django 后台列表 自定义修改单元格中字体颜色 图文教程

    Python3 Django 后台列表 自定义修改单元格中字体颜色 图文教程

    需求描述

    在Django的后台实际开发过程中,我们直接建立模型后可以很快的生成一个列表。那么如何在后台list列表中自定义某个列的单元格中的字体颜色呢?效果如下图所示:

    代码实例

    在 admin.py 中自定义一个方法, statusColored :

    from scheduling import models
    from django.utils.html import format_html
    class ComputerRoomAdmin(admin.ModelAdmin):
        list_display = ('id', 'name','type','statusColored','weights')
        list_display_links = ('id','name')  
        ordering = ('-status','weights',)
        list_filter = ('type','status')
        def statusColored(self , obj):
            if obj.status == 0:
                return format_html('<span style="color:red">{}</span>','停用')
            else:
                return format_html('<span style="color:green">{}</span>','在用')
        statusColored.short_description = "状态"
    
    admin.site.register(models.ComputerRoom , ComputerRoomAdmin)

    models.py 模型中,我们的设置为 choices

        statusChoices = (
            (0,'停用'),
            (1,'在用')
        )
        status = models.IntegerField( choices=statusChoices,verbose_name='状态' , default=1 )

  • django输出html内容

    django输出html内容

    最近在学习django,于是就用django做了一个简单的网站,用来练手,具体功能就是从网上抓取数据,然后放到我的网站上面,但是遇到一个问题就是django无法输出html格式的内容,只能以字符串的形式输出:

    data = '<h1>hello world</h1>'
    <p>{{ data }}</p>

    我们目的是输出的是:

    hello world

    但是结果输出的是:

    <h1>hello world</h1>

    在网上搜了好久,终于找到解决办法:

    对于单个变量使用django的过滤器,告诉Django这个字符串不用进行HTML转义,方法如下:

    data | safe

    对于一段模板内容可以使用autoescape标签,比如:

    {% autoescape off %}
         {{ data }}
     {% endautoescape %}

    off 的意思是关闭对html的转义,而将off替换成on就表示进行html转义,默认进行html转义

    注意:autoescape 具备继承性的,如果在父模版中定义了,则在子模版对应内容部分也存在此属性

    我们可能会疑问,django为什么要将这些字符转义,而不是按原本html的内容输出呢?
    我们举个例子:
    需要用户输入用户名来注册,这个用户输入了用户名为:

    <script type="text/javascript">alert('hello');</script>

    假设他输入的长度合法,而且django也确实没显式提供什么特殊字符转换方法,那么每次在网页上面显示的时候,岂不是每次都弹出一个窗口,那么不是就很不安全啦。
    为了解决这个问题,django默认将所有特殊的字符都转换成在html上面可以显示的内容,而不再包含转义功能!于是,也就出现了上面我想输出而输出而输出不了html的内容。

  • django models 在Django queryset如何过滤数据结果?怎么实现不等于?

    django models 在Django queryset如何过滤数据结果?怎么实现不等于?

    在Django的实际项目开发中,我们会使用到 不等于的情况,比如我想查询id!=3的结果,下面直接给出代码实例。

    方法一

    from django.db.models import Q
    Model.objects.filter(~Q(id = 3))

    方法二

    Model.objects.filter(xxxxxxxx).exclude(id=3)
  • Django 后台开发 为某个模型添加额外Javascript引用

    Django 后台开发 为某个模型添加额外Javascript引用

    最近在学Python,正好在一个项目中使用到了Django。网上查了很多资料如何为一个模型额外引用Javascript,基本都说得很简单并没有说到哪个文件哪个位置说的很笼统,对于初学者来说并不是很了解。这里记录一下如何为某个表增删改查时增加额外的 Javascript 。

    在应用的 admin.py 中配置即可,目录结构如上图所示:

    class ComputerRoomAdmin(admin.ModelAdmin):
        list_display = ('id', 'name','type','weights')
        list_display_links = ('id','name')  
        ordering = ('-weights',)
        class Media:
            js = ('/static/computerroom.js',)
    admin.site.register(models.ComputerRoom , ComputerRoomAdmin)

    这里的 js 即为需要使用的 Javascript 。

  • Django css Javascript 静态文件404 解决办法 图文教程

    Django css Javascript 静态文件404 解决办法 图文教程

    问题描述

    按照django的默认配置,django无法直接读取成功静态文件,网站的样式css和js无法成功读取,总是报404错误。Django 后台开发 为某个模型添加额外Javascript引用

    默认静态文件的相关配置为

    settings.py
    import os
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'web',
    ]
    STATIC_URL = '/static/'
    

    最佳解决办法

    这是django中针对windows的静态/媒体/模板访问的工作解决方案

    import os.path
    STATIC_ROOT = ''
    STATIC_URL = '/static/'
    STATICFILES_DIRS = ( os.path.join('static'), )
    

    添加完毕后,可以正常访问静态资源。

    随后删掉添加的内容后依然可以访问静态资源,可能跟windows有关系。

  • Docker 下使用Centos系统镜像安装 uwsgi 运行 Python3 Django Nginx 反向代理

    Docker 下使用Centos系统镜像安装 uwsgi 运行 Python3 Django Nginx 反向代理

    需求描述

    最近老季在用Python3,Django写项目,这边具体记录一下在Docker下如何安装uwsgi来运行Django。

    注意:本项目代码已在宿主中生成过项目及文件,创建项目方法请移步:django入门教程 创建项目(Project)和应用(App)

    宿主Docker命令

    docker run -itd -v D:\wwwroot\:/data/wwwroot -p 8001:9000 --name juwsgi --link jnginx --link jmysql centos /usr/sbin/init

    这里我们只在linux系统中安装了 uwsgi 来运行python的web环境,mysql已单独运行在其他容器中。

    创建映射文件

    在 d:\wwwroot\traffic_scheduling 中创建 uwsgi.ini 的配置文件

    [uwsgi]
    # Django-related settings 
    # the base directory (full path) 
    chdir = /data/wwwroot/traffic_scheduling/web/
    # Django's wsgi file 
    module = web.wsgi 
    # the virtualenv (full path) 
    # home = /path/to/virtualenv 
    # process-related settings 
    master master = true 
    # maximum number of worker processes 
    processes = 2
    # the socket (use the full path to be safe) 
    # socket = /path/to/your/project/mysite.sock 
    socket = :9000
    # ... with appropriate permissions - may be needed 
    # chmod-socket = 664 
    # clear environment on exit 
    vacuum = true
    buffer-size = 32768
    pidfile = /tmp/uwsgi-IRM.pid   
    daemonize = /tmp/uwsgi-IRM.log
    

    uwsgi中的socket

    uwsgi监听的socket,可以为socket文件

    socket = /www/wwwroot/web/script/uwsgi.sock

    或 ip地址+端口号

    socket = :9000

    用nginx的时候就配socket , 直接运行的时候配 http
    指定IP端口 // 直接外部访问

    http-socket = :9000

    进入容器

    docker exec -it juwsgi /bin/bash

    在容器中运行命令

    1、在Centos容器中运行安装Python3

    CentOS上安装配置Python3.7 编译安装图文教程

    2、在容器中运行pip命令

    pip install --upgrade pip
    pip install django mysqlclient uwsgi
    ln -s /usr/local/bin/uwsgi /usr/bin/uwsgi

    测试你的Django项目

    现在,我们想让uWSGI做同样的事,但是返回一个Django站点而不是 test.py 模块。

    如果你还没有这样做,那么请确保你的 mysite 项目实际上正常工作,在终端中运行如下命令:

    python manage.py runserver 0.0.0.0:9000

    在浏览器中输入 http://127.0.0.1:9000 。

    如果正常,在终端中ctrl + c 取消,然后在终端中进入目录 /data/wwwroot/traffic_scheduling/web/ ,则使用uWSGI来运行它:

    uwsgi --http :9000 --module web.wsgi
    • module web.wsgi: 加载指定的wsgi模块

    将你的浏览器指向该服务器;如果站点出现,那么意味着uWSGI可以为你虚拟环境中的Django应用服务,而这个栈工作正常:

    the web client <-> uWSGI <-> Django
    

    现在,通常我们不会让浏览器直接与uWSGI通信。那是web服务器的工作,这是个穿针引线的活。

    配置Nginx容器

    Docker 安装 Nginx 映射本地文件 多虚拟主机 图文教程

    示例配置文件如下

    # mysite_nginx.conf
    # the upstream component nginx needs to connect to
    upstream django {
        # server unix:///path/to/your/mysite/mysite.sock; # for a file socket
        server 127.0.0.1:9000; # for a web port socket (we'll use this first)
    }
    # configuration of the server
    server {
        # the port your site will be served on
        listen      8001;
        # the domain name it will serve for
        server_name .example.com; # substitute your machine's IP address or FQDN
        charset     utf-8;
        # max upload size
        client_max_body_size 75M;   # adjust to taste
        location /static {
            root /data/wwwroot/traffic_scheduling/web/; # your Django project's static files - amend as required
        }
        # Finally, send all non-media requests to the Django server.
        location / {
            uwsgi_pass  django;
            include     uwsgi_params; # the uwsgi_params file you installed
        }
    }

    Centos下请关闭SELinux,否则会出现 403 forbidden (13: Permission denied) 。关闭SELinux的两种方法

    部署静态文件

    在运行nginx之前,你必须收集所有的Django静态文件到静态文件夹里。首先,必须编辑web/settings.py,添加:

    STATIC_ROOT = os.path.join(BASE_DIR, "static")

    然后运行

    python manage.py collectstatic
    

    基本的nginx测试

    重启nginx:

    /etc/init.d/nginx restart

    要检查是否正确的提供了媒体文件服务,添加一个名为 media.png 的图像到 /data/wwwroot/traffic_scheduling/web/static 目录中,然后访问http://example.com:8000/media/media.png – 如果这能正常工作,那么至少你知道nginx正在正确的提供文件服务。

    值得不仅仅是重启nginx,而是实际停止然后再次启动它,这将会通知是否有问题,以及问题在哪里。

    在宿主中查看是否可以成功运行

    在浏览器中输入 http://127.0.0.1:8001 查看是否运行成功。

WeChat
↑