Colderleo's blog Colderleo's blog
首页
Linux
C++
Python
前端
工具软件
mysql
索引
关于
GitHub (opens new window)

Colder Leo

热爱代码的打工人
首页
Linux
C++
Python
前端
工具软件
mysql
索引
关于
GitHub (opens new window)
  • 1-django使用
    • Django
    • simpleui 使用方法-更换后台主题
    • 其他用法
  • centos部署Nginx+uwsgi+django - blog
  • django-admin完全自定义某个模块的页面
  • easy_select2 编辑页面添加外键选择搜索
  • 使用vscode开发python
  • python自定义异常处理with,上下文context管理器
  • python读写excel,xlsx 模块选择
  • python多线程多进程协程
  • TemporaryFile
  • threading用法
  • ubantu设置python优先级
  • conda anacodna 命令行用法
  • 我写的常用工具函数
  • 0-python常用函数
  • smtp发送邮件
  • pandas用法
  • datetime类,时间差
  • format
  • enumerate遍历数组时获取index
  • argv
  • generator 生成器
  • GIL锁、多线程
  • linux用源文件安装python3
  • list sort排序
  • logging日志
  • mulitporcessing共享变量
  • OrderedDict
  • path
  • pip用法
  • pymysql用法 - python连接mysql
  • python bash解释器,脚本前两行,
  • python docstring格式 PEP 257
  • python logging获取logger信息
  • python交互式窗口如何进行多行输入
  • virtualenv用法
  • 标准差
  • 单例模式
  • 函数中定义static变量
  • 切片
  • 去掉字符串中emoji字符
  • 去掉字符串中的空行
  • 全局变量、global和nonlocal
  • 文字识别pytesseract
  • 析构函数和del
  • 用python制作游戏外挂
  • 正则表达式,函数替换字符串
  • 装饰器
  • pycharm中运行pyqt时不报错
  • python 写文件
  • Python
gaoliu
2021-10-06
目录

1-django使用

# Django

# 常用命令快捷复制

python manage.py makemigrations
python manage.py migrate
python manage.py runserver 0.0.0.0:38090

find . -name 00*.py
find . -name 00*.py | xargs rm

python manage.py createsuperuser
django-admin startapp product

python manage.py makemigrations & python manage.py migrate --run-syncdb
1
2
3
4
5
6
7
8
9
10
11

# 参考网址链接

django官方文档,最全 https://docs.djangoproject.com/en/2.2/

刘江的django的中文系列教程,非常好,比较基础,admin自定义的部分比较少:https://www.liujiangblog.com/course/django/157

django rest framework 的一个中文博客系列教程,看起来不错,也不知道这个rest framework到底有啥用 https://www.cnblogs.com/yuzhenjie/p/10343016.html

另一个高级的教程,看起来更好,有很多自定义后台的部分: https://blog.csdn.net/weixin_42134789/article/details/83686703

自定义标签和修改listhttps://blog.csdn.net/u013378306/article/details/79030385

代理model实现一个model多个admin:https://www.it1352.com/634205.html

官方的QuickSrart教程

  • 英文教程: https://www.django-rest-framework.org/tutorial/quickstart/
  • 中文翻译: https://www.django.cn/course/show-20.html 翻译的不怎么样,看英文的更好

# Django创建项目

参考其GitHub主页,https://github.com/encode/django-rest-framework 创建了一个简单示例。

# 创建proj和app
django-admin startproject server .  # Note the trailing '.' 在根目录创建名为server的project,会创建server文件夹
django-admin startapp product #在根目录下创建名为product的app,会创建product文件夹。也可以剪切到其他地方,比如创建apps文件夹,放进去

# 在上面创建的server/settings.py中找到INSTALLED_APPS字段,加入我们创建的app,
INSTALLED_APPS = [
    'apps.product',
    ...
]

# 配置数据库连接 在server/settings.py中。默认是sqllite,如果要修改为mysql,则修改为:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'db_name',    #你的数据库名称
        'USER': 'root',   #你的数据库用户名
        'PASSWORD': 'abcd1234', #你的数据库密码
        'HOST': '127.0.0.1',  #你的数据库主机,留空默认为localhost
        'PORT': '3306', #你的数据库端口
    }
    # 'default': {
    #     'ENGINE': 'django.db.backends.sqlite3',
    #     'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    # }
}



# 数据库创建。若执行错误 Did you install mysqlclient? 则安装: pip install mysqlclient
python manage.py makemigrations # 创建migrations文件,会在各个app对应的文件夹下创建migrations文件夹,并在里面生成一些0001_***.py文件
python manage.py migrate #执行migrate,会执行sql语句


# 如果要查看某个app的某个迁移版本对应的sql语句:
python manage.py sqlmigrate product 0003


# 如果migrations执行失败时,可在数据库中直接删除该表,然后执行下面的语句,它会直接重新生成表。
python manage.py migrate --run-syncdb


# 创建superuser 和run debug server
python manage.py createsuperuser
python manage.py runserver 8090
# 如果run时端口号被占用,会提示,Error: [WinError 10013] 以一种访问权限不允许的方式... 那就换个端口号试试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

平时更新数据库可用这个:

python manage.py makemigrations & python manage.py migrate --run-syncdb
1

# 将默认sqllite更换成mysql数据库

https://blog.csdn.net/qq_37969201/article/details/87161794

pip install mysqlclient

# 不要搞这个 import pymysql     pymysql.install_as_MySQLdb()

# 在settings.py中找到DATABASE
DATABASES = {    'default': {
        'ENGINE': 'django.db.backends.mysql',    #数据库引擎
        'NAME': 'dj_experiment_db',  #数据库名
        'USER': 'root',   #账户名
        'PASSWORD': 'password', #密码
        'HOST': 'localhost', #主机
        'PORT': '3306', #端口
    }
 
}


# 然后在settings.py文件中设置TIME_ZONE为自己的时区
TIME_ZONE = 'Asia/Shanghai'

# 最后执行数据库迁移命令
python manage.py makemigrations
python manage.py migrate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# simpleui 使用方法-更换后台主题

# django-simpleui 简介

  • django-simpleui是对django-admin的美化版本。

  • django-admin是django自带的admin后台网站管理模块,可以将用户创建的数据库model自动转换成网页,对数据进行编辑管理,非常方便,节约大量的开发时间。

GitHub地址: https://github.com/newpanjing/simpleui 官网: https://simpleui.88cto.com/

vue-element-admin的GitHub地址:https://github.com/PanJiaChen/vue-element-admin

# 将simple-ui移植到自己的工程文件夹中

simple-ui默认是通过pip安装的,官方的介绍中,对其进行修改时,要在pip安装目录进行修改,不方便。这种方法参考simpleui文档:

https://simpleui.88cto.com/docs/simpleui/QUICK.html#开发调试
如果想在simpleui的基础上进行一些修改,可以参考以下步骤
安装simpleui到项目中
找到simpleui的目录,然后删除
克隆simpleui源码到本地
Linux、Unix、macOS环境下用软连接的方式,把项目依赖包中的simpleui目录指定到源码的simpleui目录
1
2
3
4
5
6

GitHub上的一个项目将其移植到了自己的工程中: https://github.com/Ryuchen/Bistu 参考该项目,用下面方法实现了将其移植到自己的工程中。

  1. 创建一个django工程,或者django-rest-framework工程 (首先需要对django有基本的了解。)

  2. 定义自己的templates模板,参考: https://www.jianshu.com/p/a61da9ff9fd6 在自己项目的根目录下创建templates文件夹, 并修改django的setting.py配置文件

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')], #  只用改这一行
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  1. pip安装simple-ui,然后打开其安装目录, 一般是位于python的安装目录下,\Lib\site-packages\simpleui

  2. 将simpleui安装目录下的templates文件夹下面的文件拷贝到自己的templates文件夹下面,里面只有admin和registration两个文件夹

  3. 将simple-ui安装目录下的templatetags文件夹拷贝到自己的某个已安装的app文件夹下面。已安装的app就是settings的install_apps中注册过的。可以是任意一个app,比如创建一个通用的app叫comapp:jango-admin startapp comapp,然后将templatetags拷贝到comapp文件夹下。不管放在哪个app下面,它都会生效。

  4. 将simpleui安装目录下的static文件夹拷贝到项目根目录下,并在server/setting.py中添加:

    STATICFILES_DIRS = [
         os.path.join(BASE_DIR, "static"),
    ]
    STATIC_ROOT = os.path.join(BASE_DIR, "/static/")
    
    1
    2
    3
    4
  5. 在项目根目录执行python manage.py runserver 8090运行网站,查看是否是simpleui的样式。然后修改template/admin/index.html,查看修改是否生效。

  6. 在server/settings中自定义simple-ui的一些设置,具体用法参考simple-ui官方文档

    
    # SimpleUI settings
    # https://github.com/newpanjing/simpleui/blob/master/QUICK.md
    SIMPLEUI_STATIC_OFFLINE = True
    # SIMPLEUI_FAVICON_ICON = "/static/bistu/img/logo.png"
    SIMPLEUI_LOGIN_LOGO = "/static/img/loginlogo.png"
    SIMPLEUI_INDEX_LOGO = "/static/img/logo.png"
    SIMPLEUI_LOGO = "/static/img/logo.png"
    SIMPLEUI_HOME_TITLE = '后台管理'
    SIMPLEUI_HOME_ICON = 'fas fa-tachometer-alt'
    SIMPLEUI_HOME_QUICK = True
    SIMPLEUI_HOME_INFO = False
    SIMPLEUI_HOME_ACTION = True
    SIMPLEUI_HOME_PAGE = 'comapp/home/'
    SIMPLEUI_HOME_TITLE = '首页'
    SIMPLEUI_HOME_ICON = 'fa fa-home'
    
    SIMPLEUI_CONFIG = {
        'system_keep': False,
        'menus': [
            {
                'app': 'news',
                'name': '文章管理',
                'icon': 'fa fa-book',
                'models': [
                    {
                        'name': '文章管理',
                        'icon': 'fa fa-cube',
                        'url': 'product/product/'
                    },
                    {
                        'name': '写文章',
                        'icon': 'fa fa-bell',
                        'url': 'product/riskcontrol/'
                    }
                ]
            },
            {
                'app': 'auth',
                'name': '账户管理',
                'icon': 'fas fa-user-shield',
                'models': [
                    {
                        'name': '用户',
                        'icon': 'fa fa-user',
                        'url': 'comapp/userprofile/'
                    },
                    {
                        'name': '用户组',
                        'icon': 'fa fa-users-cog',
                        'url': 'auth/group/'
                    }
                ]
            },
    
        ]
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58

# 其他用法

# 修改后台标题

https://www.cnblogs.com/yoyoketang/p/10345623.html (opens new window)

在server/urls.py中添加:

admin.site.site_header = 'xx 项目管理系统'
admin.site.site_title = '登录系统后台'
admin.site.index_title = '后台管理'
1
2
3

# 设置语言

在server/settings.py中修改:

# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
1
2
3

# admin 列表字段显示

admin列表显示只显示名称,其他列不显示 https://blog.csdn.net/kong2030/article/details/82319936 解决方法: 在admin.py中添加

list_display = ('id', 'underwriter', 'shortname', 'telephone')
1

编辑字段显示:

fields = ['prod_no', 'freq_type', 'repo_date', 'repo_file']
1

各种属性: https://www.cnblogs.com/LLBFWH/articles/10427754.html

(editable, 表示Admin中是否可以编辑)

# 自定义user和登录验证

自定义user,这篇文章非常棒: https://www.jianshu.com/p/bf7f15cc1130

自定义登录验证: https://blog.csdn.net/weixin_30735745/article/details/95486489

# 数据库model属性和添加约束、外键等

https://blog.csdn.net/Great_Zhou/article/details/82560343

class Product(models.Model):
    def __str__(self):
        return self.prod_name

    prod_name = models.CharField(max_length=200, unique=True)  
    founded_date = models.DateField()  #2018/1/24
    manager = models.CharField(max_length=200)


class HistValue(models.Model):
    def __str__(self):
        return self.prod_no
    
	# 指定外键名db_column为 prod_no ,此时在本表中创建的列名就是db_column指定的pord_no,而不是前面的变量名
    prod_no = models.ForeignKey(Product, on_delete=models.DO_NOTHING, db_column='prod_no')
    
    hist_date = models.DateField('日期', null=False)
    unit_value = models.FloatField('价格', null=False)   # 4位小数


    # 指定联合约束,django中不支持联合主键,只能创建联合约束
    class Meta:
        constraints = [models.UniqueConstraint(fields=['hist_date', 'prod_no'], name='unique_product_histdate')]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

定义模型的__str__(),可以使其作为外键被编辑时显示自己定义的名称。

# makemigrations和migrate

# 修改字段名

这是某次修改主键后,执行makemigrations时,它提示是否rename主键,选择是,生成的迁移文件。可参考此文件自己创建migarion文件来修改字段名

# Generated by Django 2.2.5 on 2020-02-19 07:40

from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('product', '0008_product_invest_manager'),
    ]

    operations = [
        migrations.AlterField(
            model_name='product',
            name='record_no',
            field=models.CharField(max_length=200, unique=True, verbose_name='代码'),
        ),
    ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 设置默认值

model中增加一个联合约束后执行makemigrations,提示没有默认值,让选两个选项: 1. 设置一个默认值, 2 中止执行,在model.py中设置默认值。此时生成的migraion文件如下:

class Migration(migrations.Migration):

    dependencies = [
        ('product', '0011_auto_20200221_1058'),
        ('cust', '0002_auto_20200221_1203'),
    ]

    operations = [
        migrations.AddField(
            model_name='custinfo',
            name='prod_no',
            field=models.ForeignKey(db_column='prod_no', default=1, on_delete=django.db.models.deletion.DO_NOTHING, to='product.Product'),
            preserve_default=False,
        ),
        migrations.AddConstraint(
            model_name='custinfo',
            constraint=models.UniqueConstraint(fields=('cust_id', 'prod_no'), name='unique_product_cust'),
        ),
    ]


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 执行makemigration不生效的原因:

http://www.chenxm.cc/article/187.html

自己手动添加的app,app文件夹下面没有migration文件夹,以及migration下的__inin__.py,加上就好了。

# post添加csrf权限验证

在post发送的header或者params或者data中添加下面的字段,{{ csrf_token }会被django自动渲染。 参考:https://www.cnblogs.com/wangwei916797941/p/9283776.html

param_data.append('csrfmiddlewaretoken', '{{ csrf_token }}')
1

# post上传文件

html

<span class="file-upload"  style="float: right;">
    <div class="file-upload-text">上传文件</div>         
    <input class="file-upload-input" name="file" type="file" @change="upload"/>
</span>        
1
2
3
4

js,向vue的methods中添加上传函数

upload(e) {
    let file_obj = e.target.files[0];
    let param_data = new FormData(); //创建form对象
    param_data.append('file_obj',file_obj)//通过append向form对象添加数据
    console.log(param_data.get('file_obj')) //FormData私有类对象,访问不到,可以通过get判断值是否传进去

    param_data.append('csrfmiddlewaretoken', '{{ csrf_token }}')  //django身份认证参数
    console.log(param_data.get('csrfmiddlewaretoken'), this.csrf_token)

    // 上传选择的文件
    axios({
        method: 'post',
        url: "{% url '/do/something' %}",
        data: param_data,
        headers: {'Content-Type':'multipart/form-data'}
    })
        .then(res => {
        console.log(res)
        if(res.data.mycode)
            this.$notify({
                title: '成功',
                message: res.data.mymsg,
                type: 'success',
                position: 'top-left'
            });
        else
            this.$notify({
                title: '失败',
                message: res.data.mymsg,
                type: 'error',
                position: 'top-left'
            });
    })
        .catch(error => {
        console.log('get err: ', error)
        this.$notify({
            title: '导入失败,内部错误',
            message: '',
            type: 'error',
            position: 'top-left'
        });
    });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

css美化上传按钮

<style type="text/css">
    .file-upload {
        width: 120px;
        height: 30px;
        position: relative;
        overflow: hidden;
        border: 1px solid #317EF3 ;
        display: inline-block;
        border-radius: 4px;
        font-size: 16px;
        color: #317EF3;
        text-align: center;
        line-height: 26px;
        /* float: right; */
        margin: 10px 10px auto auto;
    }
    .file-upload-input {
        background-color: transparent;
        position: absolute;
        width: 999px;
        height: 999px;
        top: -10px;
        right: -10px;
        cursor: pointer;
    }
    .file-upload-text {
        padding-top: 2px;
    }
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 后台管理文件

  1. 下载文件时中文文件名下载不显示名称, 使用urlquote对文件名处理即可。

https://www.jianshu.com/p/aa4c54f5e25d

from django.utils.http import urlquote

def download_file(request,file_name):
    full_file_name = 'file_src/'+ file_name
    file=open(full_file_name,'rb') 
    response =FileResponse(file)  
    response['Content-Type']='application/octet-stream'  
    response['Content-Disposition']='attachment;filename="{}"'.format(urlquote(pure_filename))  
    return response
1
2
3
4
5
6
7
8
9
  1. 修改FileField在文件django-admin中自动生成的下载链接: https://www.cnblogs.com/zhaozhenguo666/p/9117709.html

# markdown

https://blog.csdn.net/duke10/article/details/81033686

# debug时使用static文件

https://docs.djangoproject.com/en/2.2/howto/static-files/

# urls.py

from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('admin/product/', include('apps.product.urls')),
    ...
] + static('/static/', document_root='/static/')
1
2
3
4
5
6
7
8
9

在urls.py中的urlpatterns后面加上一句,这样debug时,通过runserver启动后

python manage.py runserver 127.0.0.1:8090
1

也可以直接访问静态资源:127.0.0.1:8090/static/test.html

# url跳转

https://docs.djangoproject.com/en/2.2/ref/class-based-views/base/

urls.py

from django.urls import path
from django.views.generic.base import RedirectView

urlpatterns = [
    path('counter/<int:pk>/', ArticleCounterRedirectView.as_view(), name='article-counter'),
    path('details/<int:pk>/', ArticleDetail.as_view(), name='article-detail'),
    path('go-to-django/', RedirectView.as_view(url='https://djangoproject.com'), name='go-to-django'),
]
1
2
3
4
5
6
7
8

# render pdf

  1. one way: by pdfkit.from_string(content)
def html_to_pdf(content):
    options = {
        'page-size': 'A4',
    }
    # pdfkit.from_string(content, 'out_1.pdf', options=options) #generate file
    file_bytes = pdfkit.from_string(content, False, options=options)
    return file_bytes



def get_report_html(request):
    if not request.user.has_perm('customer.view_customertoproduct'):
        return HttpResponse('forbidden', status=403)
    step = int(get_param(request, 'step'))
    prod_no = get_param(request, 'prod_no')
    customer_id = get_param(request, 'customer_id')
    return_type = get_param(request, 'type')

    upload_system_path = os.path.join(settings.BASE_DIR, 'upload', 'customer_material')
    cp:CustomerToProduct = CustomerToProduct.objects.get(customer_id=customer_id, prod_no=prod_no)
    prod_name = str(cp.prod_no.prod_name)

    # variables can be used in report.html like {{prod_name}}, {{cp.next_step}}
    t = TemplateResponse(request, f'report.html', locals())
    if return_type=='html':
        return t

    # default return pdf preview
    t.render()
    pdf = html_to_pdf(t.content.decode('utf-8'))
    
    response = HttpResponse(pdf)
    response['Content-Type'] = "application/pdf"
    if return_type=='download':
        response['Content-Disposition'] = 'attachment;filename="{}"'.format(urlquote(f'步骤{step+1}.pdf'))  
    return response

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
  1. another way: by pdfkit.from_url(url)

访问html连接,生成pdf,返回:

def a_view(request):
    pdf_bytes = pdfkit.from_url(html_url, False)
    response = HttpResponse(pdf_bytes)
    response['Content-Type'] = "application/pdf"
    if 'download':
        response['Content-Disposition'] = 'attachment;filename="{}"'.format(urlquote('文件A.pdf'))
    return response
1
2
3
4
5
6
7

# check_perm

# contrib\admin\options.py

@csrf_protect_m
def changelist_view(self, request, extra_context=None):
    """
        The 'change list' admin view for this model.
        """
    from django.contrib.admin.views.main import ERROR_FLAG
    opts = self.model._meta
    app_label = opts.app_label
    if not self.has_view_or_change_permission(request):
        raise PermissionDenied
1
2
3
4
5
6
7
8
9
10
11
12

# 扩展阅读

Django中的JWT(Json Web Token认证机制) (opens new window)

# 设置server/settings.py

按照下面的设置,少踩坑。

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
STATICFILES_DIRS = [
     os.path.join(BASE_DIR, "static"),
]
STATIC_ROOT = os.path.join(BASE_DIR, "/static/")
STATIC_URL = '/static/'

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

TIME_FORMAT = '%Y-%m-%d %H:%M:%S'
DATE_TIME_FORMAT = '%Y-%m-%d'

# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/

# LANGUAGE_CODE = 'en-us'
# TIME_ZONE = 'UTC'
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
# USE_TZ = True
USE_TZ = False

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
编辑 (opens new window)
上次更新: 2023/05/07, 17:27:54
centos部署Nginx+uwsgi+django - blog

centos部署Nginx+uwsgi+django - blog→

最近更新
01
通过模板实现结构体成员拷贝-按成员名匹配
05-07
02
c++17通过模板获取类成员的个数
05-01
03
avx-sse切换惩罚
04-30
更多文章>
Theme by Vdoing | Copyright © 2019-2023 Colder Leo | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×