创建项目

django-admin startproject 项目名称

创建APP

python manage.py startapp 程序名称

注册APP【settings.py】

image.png

编写url与视图函数的对应关系

  • 在 urls.py ,路由 ( URL 和 函数的对应关系)。

在urls.py文件中导入views
编写对应关系
image.png

编写视图函数

  • 在views.py,视图函数,编写业务逻辑。

在views.py中导入HttpResponse
编写对应的函数
image.png

  • 视图函数

默认参数request,包含请求相关的所有数据。
request.method
request.GET
request.POST
request.FILES,上传文件。
request.path_info,获取当前请求的URL
http://127.0.0.1:8000/depart/add/ -> /depart/add/

  1. def admin_list(request):
  2. k1 = request.POST.get("k1")
  3. ... 业务处理
  4. return 数据
  5. - 默认参数request,包含请求相关的所有数据。
  6. request.method
  7. request.GET
  8. request.POST
  9. request.FILES,上传文件。
  10. request.path_info,获取当前请求的URL
  11. http://127.0.0.1:8000/depart/add/ -> /depart/add/
  12. - 返回值
  13. return HttpResponse("字符串")
  14. return JSONResponse( {"status":123,"data":[456,55,66,22,]} )
  15. return JSONResponse( [11,22,33,44] ,safe=False)
  16. return render(request,"xxx.html",{值})
  17. return redirect("http://127.0.0.1:8000/depart/add/")
  18. return redirect("/depart/add/")

启动django项目

  1. python manage.py runserver

创建templates文件夹

创建静态文件夹

image.png

引用静态文件

image.png

设置数据库为mysql

安装第三方模块

pip install mysqlclient

django连接数据库

在settings.py文件中进行配置和修改。

  1. DATABASES = {
  2. 'default': {
  3. 'ENGINE': 'django.db.backends.mysql',
  4. 'NAME': 'gx_day15', # 数据库名字
  5. 'USER': 'root',
  6. 'PASSWORD': 'root123',
  7. 'HOST': '127.0.0.1', # 那台机器安装了MySQL
  8. 'PORT': 3306,
  9. }
  10. }

根据迁移文件去创建数据库表结构

python manage.py migrate
image.png
关闭重连数据库,查看
image.png

从数据库导出生成models.py,在lms目录下得到models.py

python manage.py inspectdb > models.py
将导出的models.py文件替换原有的app内的文件

生成迁移文件

python manage.py makemigrations 程序名称

根据迁移文件去创建数据库表结构

python manage.py migrate

模板的继承

templates目录,编写HTML模板(含有模板语法、继承、{% static ‘xx’%})

定义模板:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <link rel="stylesheet" href="{% static 'plugin...min.css' %}">
  7. {% block css %}{% endblock %}
  8. </head>
  9. <body>
  10. <h1>标题</h1>
  11. <div>
  12. {% block content %}{% endblock %}
  13. </div>
  14. <h1>底部</h1>
  15. <script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
  16. {% block js %}{% endblock %}
  17. </body>
  18. </html>

继承模板:

  1. {% extends 'layout.html' %}
  2. {% block css %}
  3. <link rel="stylesheet" href="{% static 'pluxxx.css' %}">
  4. <style>
  5. ...
  6. </style>
  7. {% endblock %}
  8. {% block content %}
  9. <h1>首页</h1>
  10. {% endblock %}
  11. {% block js %}
  12. <script src="{% static 'js/jqxxxin.js' %}"></script>
  13. {% endblock %}

初识Form

ModelForm & Form组件,在我们开发增删改查功能

  • 生成HTML标签(生成默认值)
  • 请求数据进行校验。
  • 保存到数据库(ModelForm)
  • 获取错误信息。

    1. views.py

    ```python class MyForm(Form): user = forms.CharField(widget=forms.Input) pwd = form.CharFiled(widget=forms.Input) email = form.CharFiled(widget=forms.Input) account = form.CharFiled(widget=forms.Input) create_time = form.CharFiled(widget=forms.Input) depart = form.CharFiled(widget=forms.Input) gender = form.CharFiled(widget=forms.Input)

def user_add(request): if request.method == “GET”: form = MyForm() return render(request, ‘user_add.html’,{“form”:form})

  1. <a name="2.user_add.html"></a>
  2. #### 2.user_add.html
  3. ```html
  4. <form method="post">
  5. {% for field in form%}
  6. {{ field }}
  7. {% endfor %}
  8. <!-- <input type="text" placeholder="姓名" name="user" /> -->
  9. </form>
  1. <form method="post">
  2. {{ form.user }}
  3. {{ form.pwd }}
  4. {{ form.email }}
  5. <!-- <input type="text" placeholder="姓名" name="user" /> -->
  6. </form>

ModelForm(推荐)

  1. from django.forms import ModelForm
  2. from app01 import models

0. models.py

  1. class UserInfo(models.Model):
  2. """ 员工表 """
  3. name = models.CharField(verbose_name="姓名", max_length=16)
  4. password = models.CharField(verbose_name="密码", max_length=64)
  5. age = models.IntegerField(verbose_name="年龄")
  6. account = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0)
  7. create_time = models.DateTimeField(verbose_name="入职时间")
  8. depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)
  9. gender_choices = (
  10. (1, "男"),
  11. (2, "女"),
  12. )
  13. gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)

1. views.py

  1. class MyForm(ModelForm):
  2. xx = form.CharField*("...")
  3. class Meta:
  4. model = UserInfo
  5. fields = ["name","password","age","xx"]
  6. def user_add(request):
  7. if request.method == "GET":
  8. form = MyForm()
  9. return render(request, 'user_add.html',{"form":form})

2.user_add.html

  1. <form method="post">
  2. {% for field in form%}
  3. {{ field }}
  4. {% endfor %}
  5. <!-- <input type="text" placeholder="姓名" name="user" /> -->
  6. </form>
  1. <form method="post">
  2. {{ form.user }}
  3. {{ form.pwd }}
  4. {{ form.email }}
  5. <!-- <input type="text" placeholder="姓名" name="user" /> -->
  6. </form>

form/modelform设置样式

image.png

modelform设置填充数据

image.png

校验和保存数据

  • 通过 form = DetailForm(data=request.POST) 接收用户提交的数据
  • 通过 form.is_valid() 进行校验
  • 通过 form.save() 保存数据
  • 如果没通过校验,返回当前页面及当前的form对象,其包含错误信息
    1. def edittest(request, nid):
    2. # 获取填充的数据
    3. row_object = models.Detail.objects.filter(id=nid).first()
    4. if request.method == "GET":
    5. form = DetailForm(instance=row_object)
    6. return render(request, 'edittest.html', {'form': form})
    7. # 提交用户的请求
    8. form = DetailForm(data=request.POST, instance=row_object)
    9. # 进行校验
    10. if form.is_valid():
    11. # 保存数据
    12. form.save()
    13. return redirect('/test/show')
    14. print('error')
    15. return render(request, "edittest.html", {'form': form}) # 包含错误信息
    html设置:
    image.png

    后台管理系统配置设置

    配置文件

    lms/lms/settings.py ```python

    关闭DEBUG模式:

    DEBUG = False # 修改
    ALLOWED_HOSTS = [‘*’, ] # 修改

添加simpleui、导入导出应用

INSTALLED_APPS = [

注意:这里一定要把simpleui放在最前面

  1. 'simpleui', # 添加
  2. 'import_export', # 添加
  3. 'django.contrib.admin',
  4. 'django.contrib.auth',
  5. 'django.contrib.contenttypes',
  6. 'django.contrib.sessions',
  7. 'django.contrib.messages',
  8. 'django.contrib.staticfiles',

]

默认首页设置

SIMPLEUI_HOME_INFO = False # 添加,去掉首页右侧多余部分

SIMPLEUI_LOGO = ‘xxx’ # 可选添加,换成自己Logo链接

设置语言、时区

LANGUAGE_CODE = ‘zh-hans’ # 修改,更改默认语言为中文 TIME_ZONE = ‘Asia/Shanghai’ # 修改,更改时区 USE_TZ = False # 修改

collectstatic静态资源路径设置

STATIC_ROOT = ‘static’ # 添加

  1. <a name="QdeN8"></a>
  2. ### 迁移静态文件
  3. ```shell
  4. python manage.py collectstatic

执行成功后,会在manage.py相同路径下创建static文件夹

系统标题设置

lms/lms/urls.py

  1. from django.contrib import admin
  2. from django.urls import path
  3. from django.views import static
  4. from django.conf import settings
  5. from django.urls import include, re_path
  6. admin.site.site_header = '左上角和登录页'
  7. admin.site.site_title = '我在浏览器标签'
  8. admin.site.index_title = '我在后台首页'
  9. urlpatterns = [
  10. path('admin/', admin.site.urls),
  11. re_path(r'^static/(?P<path>.*)$', static.serve,
  12. {'document_root': settings.STATIC_ROOT}, name='static'),
  13. ]

image.png

启动项目

初始化数据库

  1. python manage.py migrate

image.png

创建超级管理员

  1. # 首先,我们得创建一个能登录管理页面的用户。
  2. python manage.py createsuperuser
  3. # 输入你想要使用的用户名,然后按下回车键:
  4. Username: admin
  5. # 然后输入想要使用的邮件地址:
  6. Email address: admin@example.com
  7. # 最后一步是输入密码。你会被要求输入两次密码,第二次的目的是为了确认第一次输入的确实是你想要的密码。
  8. Password: **********
  9. Password (again): *********
  10. Superuser created successfully.

image.png

启动项目

  1. python manage.py runserver 8000

image.png

浏览器打开127.0.0.1:8000/admin,输入账号密码,进入系统
image.png
image.png

将应用注册到管理页面

lms/library/admin.py

  1. from django.contrib import admin
  2. from .models import Detail # 增加
  3. # Register your models here.
  4. admin.site.register(Detail) # 增加

image.png

配置菜单中文名

lms/library/apps.py

  1. class App01Config(AppConfig):
  2. default_auto_field = 'django.db.models.BigAutoField'
  3. name = 'app01'
  4. verbose_name = "试题管理" # 添加

lms/library/models.py

  1. class Detail(models.Model):
  2. id = models.CharField(primary_key=True, max_length=255,
  3. auto_created=True, blank=False, verbose_name='编号')
  4. title = models.TextField(blank=True, null=True, verbose_name='题目')
  5. a = models.TextField(blank=True, null=True,verbose_name='选项A')
  6. b = models.TextField(blank=True, null=True,verbose_name='选项B')
  7. c = models.TextField(blank=True, null=True,verbose_name='选项C')
  8. d = models.TextField(blank=True, null=True,verbose_name='选项D')
  9. class Meta:
  10. managed = False
  11. db_table = 'detail'
  12. verbose_name = "试题详情管理" # 增加
  13. verbose_name_plural = "试题详情" # 增加
  14. '''
  15. class Book(models.Model):
  16. name = models.CharField(max_length=50, db_collation='utf8_general_ci', verbose_name = '书名')
  17. price = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True, verbose_name = '价格')
  18. author = models.CharField(max_length=50, db_collation='utf8_general_ci', blank=True, null=True, verbose_name = '作者')
  19. library = models.ForeignKey('Library', models.DO_NOTHING, blank=True, null=True, verbose_name = '存放仓库')
  20. num = models.PositiveIntegerField(blank=True, null=True, verbose_name = '数量')
  21. class Meta:
  22. managed = True
  23. db_table = 'book'
  24. verbose_name = "书籍管理"
  25. verbose_name_plural = "书籍管理"
  26. '''

image.png

页面字段显示设置

stgl/app01/admin.py

  1. from django.contrib import admin
  2. from .models import Detail # 增加
  3. class DetailAdmin(admin.ModelAdmin): # 增加
  4. list_display = ['id','title','a','b','c','d'] # 增加
  5. admin.site.register(Detail,DetailAdmin)

image.png

字段中文名设置

lms/library/models.py

  1. class Book(models.Model):
  2. name = models.CharField(max_length=50, db_collation='utf8_general_ci')
  3. price = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
  4. author = models.CharField(max_length=50, db_collation='utf8_general_ci', blank=True, null=True)
  5. library = models.ForeignKey('Library', models.DO_NOTHING, blank=True, null=True)
  6. num = models.PositiveIntegerField(blank=True, null=True)
  7. class Meta:
  8. managed = True
  9. db_table = 'book'
  10. verbose_name = "书籍管理"
  11. verbose_name_plural = "书籍管理"

image.png

增加搜索功能

stgl/app01/admin.py

  1. from django.contrib import admin
  2. from .models import Book
  3. class BookAdmin(admin.ModelAdmin):
  4. list_display = ['name','price','author','library','num']
  5. list_filter = ['name','author','price'] # 增加 过滤器
  6. admin.site.register(Book,BookAdmin) # 修改

image.png
image.png

增加导入导出功能

新建lms/library/resource.py

  1. from import_export import resources
  2. from .models import Detail
  3. class DetailResource(resources.ModelResource):
  4. class Meta:
  5. model = Detail

lms/library/admin.py

  1. from django.contrib import admin
  2. from .models import Detail
  3. from .resource import DetailResource # 增加
  4. from import_export.admin import ImportExportModelAdmin,ImportMixin,ExportMixin # 增加
  5. class DetailAdmin(ImportExportModelAdmin,admin.ModelAdmin):
  6. list_display = ['id','title','a','b','c','d']
  7. list_filter = ['id','title'] # 过滤器
  8. resource_class = DetailResource # 增加
  9. admin.site.register(Detail,DetailAdmin)

image.png

添加其他管理

配置admin.py,apps.py,models.py

  1. # Register your models here.
  2. from django.contrib import admin
  3. from .models import Agreement, Invitation, InvitationInfo, Comment # 增加
  4. from .resource import InvitationResource, AgreementResource, InvitationInfoResource, CommentResource # 增加
  5. from import_export.admin import ImportExportModelAdmin, ImportMixin, ExportMixin # 增加
  6. class InvitationAdmin(admin.ModelAdmin): # 增加
  7. list_display = ['id', 'title', 'content', 'state', 'picture'] # 增加
  8. list_filter = ['state'] # 过滤器 可根据字段类型进行筛选。
  9. list_editable = ['state'] # 在当前页面进行编辑,无需点击字段名进入详情页编辑。
  10. search_fields = ['title', 'content'] # 通过输入的词对title包含的字段进行筛选。
  11. resource_class = InvitationResource # 增加
  12. class AgreementAdmin(admin.ModelAdmin): # 增加
  13. list_display = ['invi', 'user'] # 增加
  14. list_filter = ['invi', 'user'] # 过滤器 可根据字段类型进行筛选。
  15. search_fields = ['invi', 'user'] # 通过输入的词对title包含的字段进行筛选。
  16. resource_class = AgreementResource # 增加
  17. class CommentAdmin(admin.ModelAdmin): # 增加
  18. list_display = ['id', 'content', 'category', 'info_id',
  19. 'user', 'time', ] # 增加
  20. # list_filter = ['invi', 'user'] # 过滤器 可根据字段类型进行筛选。
  21. # list_editable = ['invi', 'user'] # 在当前页面进行编辑,无需点击字段名进入详情页编辑。
  22. # search_fields = ['invi', 'user'] # 通过输入的词对title包含的字段进行筛选。
  23. resource_class = CommentResource # 增加
  24. class InvitationInfoAdmin(admin.ModelAdmin): # 增加
  25. list_display = ['invi', 'user', 'time'] # 增加
  26. # list_filter = ['invi', 'user'] # 过滤器 可根据字段类型进行筛选。
  27. # list_editable = ['invi', 'user'] # 在当前页面进行编辑,无需点击字段名进入详情页编辑。
  28. # search_fields = ['invi', 'user'] # 通过输入的词对title包含的字段进行筛选。
  29. resource_class = InvitationInfoResource # 增加
  30. admin.site.register(Agreement, AgreementAdmin)
  31. admin.site.register(Invitation, InvitationAdmin)
  32. # , Comment, Agreement, InvitationInfoAdmin, CommentAdmin, AgreementAdmin
  33. admin.site.register(InvitationInfo, InvitationInfoAdmin)
  34. admin.site.register(Comment, CommentAdmin)

apps主要是设置应用的中文名

  1. from django.apps import AppConfig
  2. class CampusinfoConfig(AppConfig):
  3. default_auto_field = 'django.db.models.BigAutoField'
  4. name = 'campusInfo'
  5. verbose_name = "校园资讯" # 添加

如果需要设置导入导出功能,则需要创建文件resource.py

  1. from import_export import resources
  2. from .models import Agreement, Invitation, InvitationInfo, Comment
  3. class InvitationResource(resources.ModelResource):
  4. class Meta:
  5. model = Invitation
  6. class AgreementResource(resources.ModelResource):
  7. class Meta:
  8. model = Agreement
  9. class CommentResource(resources.ModelResource):
  10. class Meta:
  11. model = Comment
  12. class InvitationInfoResource(resources.ModelResource):
  13. class Meta:
  14. model = InvitationInfo

时间字段显示格式

lms/lms/settings.py

  1. #时间格式
  2. USE_L10N = False # 增加
  3. DATETIME_FORMAT = 'Y-m-d H:i:s' # 增加
  4. DATE_FORMAT = 'Y-m-d' # 增加

设置登录验证码(配置)

lms/lms/settings.py

  1. INSTALLED_APPS = [
  2. 'simpleui',
  3. 'import_export',
  4. 'multi_captcha_admin', # 添加
  5. 'django.contrib.admin',
  6. 'django.contrib.auth',
  7. 'django.contrib.contenttypes',
  8. 'django.contrib.sessions',
  9. 'django.contrib.messages',
  10. 'django.contrib.staticfiles',
  11. ]
  12. # 验证码配置,添加
  13. MULTI_CAPTCHA_ADMIN = {
  14. 'engine': 'simple-captcha',
  15. }
  16. # 验证码图片大小,添加
  17. CAPTCHA_IMAGE_SIZE = (78, 35)
  18. # 字符个数,添加
  19. CAPTCHA_LENGTH = 4
  20. # 超时,添加
  21. CAPTCHA_TIMEOUT = 1
  22. # 设置templates路径
  23. TEMPLATES = [
  24. {
  25. 'BACKEND': 'django.template.backends.django.DjangoTemplates',
  26. 'DIRS': ['templates'], # 修改这里
  27. 'APP_DIRS': True,
  28. 'OPTIONS': {
  29. 'context_processors': [
  30. 'django.template.context_processors.debug',
  31. 'django.template.context_processors.request',
  32. 'django.contrib.auth.context_processors.auth',
  33. 'django.contrib.messages.context_processors.messages',
  34. ],
  35. },
  36. },
  37. ]

lms/lms/urls.py

  1. urlpatterns = [
  2. path('admin/', admin.site.urls),
  3. path('captcha/', include('captcha.urls')), # 添加
  4. re_path(r'^static/(?P<path>.*)$', static.serve,
  5. {'document_root': settings.STATIC_ROOT}, name='static'),
  6. ]

在lsm/templates/admin路径下新建login.html,内容如下

  1. <!DOCTYPE html>
  2. {% load i18n static simpletags %}
  3. {% get_current_language as LANGUAGE_CODE %}{% get_current_language_bidi as LANGUAGE_BIDI %}
  4. <!--
  5. The project use: django-simpleui
  6. source code:
  7. https://github.com/newpanjing/simpleui
  8. -->
  9. <html lang="{{ LANGUAGE_CODE|default:"en-us" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
  10. <head>
  11. <meta charset="UTF-8">
  12. <meta name="renderer" content="webkit">
  13. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  14. <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  15. {% block title %}
  16. <title>{{ site_title }}-{% trans 'Log in' %}</title>
  17. {% endblock %}
  18. {% block icon %}
  19. {# <link rel="icon" href="{% static 'admin/simpleui-x/img/favicon.png' %}">#}
  20. {% endblock %}
  21. {% include 'admin/includes/css-part.html' %}
  22. {% block css %}
  23. <link rel="stylesheet" href="{% static 'admin/simpleui-x/css/login.css' %}?_=2.1">
  24. {% endblock %}
  25. {% block bg %}
  26. <style type="text/css">
  27. .bg {
  28. background: #f0f2f5;
  29. background-image: url('{% static 'admin/simpleui-x/img/bg.svg' %}');
  30. min-height: 100%;
  31. background-repeat: no-repeat;
  32. background-position: 50%;
  33. background-size: 100%;
  34. padding: 20px 0;
  35. position: relative;
  36. }
  37. </style>
  38. <style type="text/css">
  39. #id_captcha_1{
  40. position: absolute;
  41. margin:0 0 0 5px; /*上右下左*/
  42. width: 265px;
  43. font-size: inherit;
  44. -webkit-appearance: none;
  45. border-radius: 4px;
  46. border: 1px solid #DCDFE6;
  47. box-sizing: border-box;
  48. display: inline-block;
  49. height: 40px;
  50. line-height: 40px;
  51. outline: 0;
  52. padding: 0 15px;
  53. transition: border-color .2s cubic-bezier(.645,.045,.355,1);
  54. text-align: center;
  55. }
  56. </style>
  57. {% endblock %}
  58. {% block head %}
  59. {# You can add code here. #}
  60. {% endblock %}
  61. </head>
  62. <body class="bg">
  63. {% block main %}
  64. <div class="login-main">
  65. {% block logo %}
  66. <div class="logo">
  67. {% if "SIMPLEUI_LOGO"|get_config %}
  68. <img src="{{ "SIMPLEUI_LOGO"|get_config |safe }}">
  69. {% else %}
  70. <img src="{% static 'admin/simpleui-x/img/logo.png' %}">
  71. {% endif %}
  72. </div>
  73. {% endblock %}
  74. {% block header %}
  75. <div class="header">{{ site_header }}</div>
  76. {% endblock %}
  77. {% block errors %}
  78. {% if form.non_field_errors %}
  79. {% for error in form.non_field_errors %}
  80. <el-alert
  81. title="{{ error }}"
  82. type="error">
  83. </el-alert>
  84. {% endfor %}
  85. {% endif %}
  86. {% if form.errors and not form.non_field_errors %}
  87. <p class="errornote">
  88. {% if form.errors.items|length == 1 %}
  89. <el-alert title="{% trans "Please correct the error below." %}" type="error"></el-alert>
  90. {% else %}
  91. <el-alert title="{% trans "Please correct the errors below." %}" type="error"></el-alert>
  92. {% endif %}
  93. </p>
  94. {% endif %}
  95. {% endblock %}
  96. {% block form %}
  97. <form class="simpleui-form" action="{{ app_path }}" method="post" id="login-form">
  98. {% csrf_token %}
  99. <div class="simpleui-input-inline">
  100. <el-input prefix-icon="fas fa-user" v-model="username" name="username"
  101. placeholder="{% trans 'username' %}" autofocus></el-input>
  102. </div>
  103. <div class="simpleui-input-inline">
  104. <el-input prefix-icon="fas fa-lock" type="password" v-model="password" name="password"
  105. @keyup.enter.native="login()"
  106. placeholder="{% trans 'password' %}" show-password></el-input>
  107. </div>
  108. <div>
  109. {{ form.captcha }}
  110. </div>
  111. {% url 'admin_password_reset' as password_reset_url %}
  112. {% if password_reset_url %}
  113. <div class="password-reset-link">
  114. <a class="forgot-password" href="{{ password_reset_url }}">{% trans 'Forgotten your password or username?' %}</a>
  115. </div>
  116. {% endif %}
  117. <div class="simpleui-input-inline login-btn">
  118. <el-button :icon="loading?'el-icon-loading':''" @click="login()"
  119. type="primary">{% trans 'Log in' %}</el-button>
  120. </div>
  121. <input type="hidden" name="next" value="{{ next }}"/>
  122. </form>
  123. {% endblock %}
  124. </div>
  125. {% endblock %}
  126. {% include 'admin/includes/js-part.html' %}
  127. {% block login_js %}
  128. <script type="text/javascript" src="{% static 'admin/js/jquery.min.js' %}"></script>
  129. <script>
  130. $(function(){
  131. $('img.captcha').click(function () {
  132. $.getJSON("/captcha/refresh/", function (result) {
  133. console.log(result);
  134. $('img.captcha').attr('src', result['image_url']);
  135. $('#id_captcha_0').val(result['key'])
  136. });
  137. });
  138. $(document).keyup(function(event){
  139. if(event.keyCode ==13){
  140. $('#login-form > div.simpleui-input-inline.login-btn > button').trigger("click");
  141. }
  142. });
  143. })
  144. </script>
  145. <script type="text/javascript" src="{% static 'admin/simpleui-x/js/login.js' %}?_=3.3"></script>
  146. {% endblock %}
  147. {% block particles %}
  148. {% if 'SIMPLEUI_LOGIN_PARTICLES'|get_config != False %}
  149. <!--
  150. Close login page particles see link:
  151. 关闭登录页粒子动画请查看:
  152. https://github.com/newpanjing/simpleui/blob/master/QUICK.md#关闭登录页粒子动画
  153. -->
  154. <style type="text/css">
  155. #particles-js {
  156. position: fixed;
  157. top: 0px;
  158. left: 0px;
  159. right: 0px;
  160. bottom: 0px;
  161. z-index: -1;
  162. }
  163. .forgot-password {
  164. margin-top: 10px;
  165. color: #3a8ee6;
  166. text-decoration: none;
  167. &:hover,
  168. &:active,
  169. &:focus {
  170. color: lighten($teal, 7);
  171. }
  172. }
  173. </style>
  174. <!-- particles.js container -->
  175. <div id="particles-js"></div>
  176. <script type="text/javascript" src="{% static 'admin/simpleui-x/particles/particles.js' %}"></script>
  177. <script type="text/javascript" src="{% static 'admin/simpleui-x/particles/app.js' %}"></script>
  178. {% endif %}
  179. {% endblock %}
  180. </body>
  181. </html>
  1. # 上述文件来自simpleui默认登录文件,添加代码说明
  2. # lmsenv\Lib\site-packages\simpleui\templates\admin\login.html
  3. 4159行: 设置验证码输入框样式
  4. 114116行:验证码位置
  5. 136152行:验证码点击刷新功能

下载https://cdn.bootcdn.net/ajax/libs/jquery/3.5.0/jquery.min.js,将jquery.min.js文件放入lms/static/js下
image.png

迁移文件

  1. python manage.py migrate

image.png

浏览器打开127.0.0.1:8000/admin,输入账号密码,进入系统
image.png

一些 小tip !!!!!!!

model表字段

表字段 说明
models.AutoField 默认会生成一个名为id的字段并未int类型
models.CharField 字符串类型
models.BooleanField 布尔类型
models.ComaSeparatedIntegerField 用逗号分隔的整数类型
models.DateField 日期(Date)类型
models.DateTimeField 日期(datetime)类型
models.DecimalField 十进制小数类型
models.EmailField 字符串类型(正则表达式邮箱)
models.FloatField 浮点类型
models.IntegerField 整数类型
models.BigIntegerField 长整数类型
models。IPAddressField 字符串类型(IPV4正则表达式)
models.GenericIPAddressField 字符串类型, 参数protocol 可以是: both 、IPv4 和
ipv6 , 验证IP地址
models.NullBooleanField 允许为空的布尔类型
models.PositivelntegerFiel 正整数的整数类型
models.PositiveSmallIntegerField 小正整数类型
models.SlugField 包含字母、数字、下曲线和连字符的字符串, 常用于
URL
models.SmaIlIntegerField 小整数类型, 取值范围C -32,768—-+32,767 )
models.TextField 长文本类型
models. TimeField 时间类型, 显东时分秒HH:MM[:ss[ .uuuuuu]]
models. URLField 字符串, 地址为正则表达式
models.B inary F ield 二进制数据类型

上传文件

  1. file = request.FILES.get('logo')
  2. with open("./media/"+file.name, 'wb') as f:
  3. for i in file:
  4. f.write(i)
  5. print(file.name)

检查None或’’空字符串或False

  1. return bool(form.data.get('first_name', False))

在这种情况下,如果form.data[‘first_name’]不存在,它将是return False,如果值是,None或者’’这也将return False,如果值是True或’a string’它将return True.

设置密码加密存储

工具类,可以创建一个py文件进行导入操作

  1. from django.conf import settings
  2. import hashlib
  3. def md5(data_string):
  4. obj = hashlib.md5(settings.SECRET_KEY.encode('utf-8'))
  5. obj.update(data_string.encode('utf-8'))
  6. return obj.hexdigest()

设置后台首页导航栏的顺序

  1. class ForumsystemConfig(AppConfig):
  2. default_auto_field = 'django.db.models.BigAutoField'
  3. name = 'forumSystem'
  4. verbose_name = '论坛系统'
  5. orderIndex = 2

设置语言、时区

  1. LANGUAGE_CODE = 'zh-hans' # 修改,更改默认语言为中文
  2. TIME_ZONE = 'Asia/Shanghai' # 修改,更改时区
  3. USE_TZ = False # 修改

post请求设置

POST提交CSRF认证

  1. <form method='post'>
  2. {% csrf_token %}
  3. ...
  4. </form>

免除csrf认证

  1. from django.views.decorators.csrf import csrf_exempt
  2. @csrf_exempt
  3. def order_add(request):
  4. pass

ajax手动csrf认证

  1. $.ajax({
  2. url:'{% url "register" %}',java
  3. type:'POST',
  4. data:{
  5. ...
  6. 'csrfmiddlewaretoken', $('[name=csrfmiddlewaretoken]').val()); //手动获取csrf_token值
  7. }
  8. dataType:'JSON',
  9. success:function (res) {
  10. ...

例:sex设置

  1. gender_choices = (
  2. (1, "男"),
  3. (2, "女"),
  4. )
  5. gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)

获取数据表字段名

image.png
image.png

设置数据表字段别名

image.png

数据库中表关联

  1. from django.db import models
  2. class Department(models.Model):
  3. """ 部门表 """
  4. title = models.CharField(verbose_name='标题', max_length=32)
  5. class UserInfo(models.Model):
  6. """ 员工表 """
  7. # 想要允许为空 null=True, blank=True
  8. name = models.CharField(verbose_name="姓名", max_length=16)
  9. password = models.CharField(verbose_name="密码", max_length=64)
  10. age = models.IntegerField(verbose_name="年龄")
  11. account = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0)
  12. create_time = models.DateTimeField(verbose_name="入职时间")
  13. # 无约束
  14. # depart_id = models.BigIntegerField(verbose_name="部门ID")
  15. # 1.有约束
  16. # - to,与那张表关联
  17. # - to_field,表中的那一列关联
  18. # 2.django自动
  19. # - 写的depart
  20. # - 生成数据列 depart_id
  21. # 3.部门表被删除
  22. # ### 3.1 级联删除
  23. depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)
  24. # ### 3.2 置空
  25. # depart = models.ForeignKey(to="Department", to_field="id", null=True, blank=True, on_delete=models.SET_NULL)
  26. # 在django中做的约束
  27. gender_choices = (
  28. (1, "男"),
  29. (2, "女"),
  30. )
  31. gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)

重定向

  1. from django.shortcuts import redirect, render, HttpResponse
  2. return redirect('/test/show')

时间插件

  1. <link rel="stylesheet" href="static/plugins/bootstrap-3.4.1/css/bootstrap.css">
  2. <link rel="stylesheet" href="static/plugins/bootstrap-datepicker/css/bootstrap-datepicker.css">
  3. <input type="text" id="dt" class="form-control" placeholder="入职日期">
  4. <script src="static/js/jquery-3.6.0.min.js"></script>
  5. <script src="static/plugins/bootstrap-3.4.1/js/bootstrap.js"></script>
  6. <script src="static/plugins/bootstrap-datepicker/js/bootstrap-datepicker.js"></script>
  7. <script src="static/plugins/bootstrap-datepicker/locales/bootstrap-datepicker.zh-CN.min.js"></script>
  8. <script>
  9. $(function () {
  10. $('#dt').datepicker({
  11. format: 'yyyy-mm-dd',
  12. startDate: '0',
  13. language: "zh-CN",
  14. autoclose: true
  15. });
  16. })
  17. </script>

ModelForm和BootStrap

ModelForm可以帮助我们生成HTML标签。

  1. class UserModelForm(forms.ModelForm):
  2. class Meta:
  3. model = models.UserInfo
  4. fields = ["name", "password",]
  5. form = UserModelForm()

定义插件

  1. class UserModelForm(forms.ModelForm):
  2. class Meta:
  3. model = models.UserInfo
  4. fields = ["name", "password",]
  5. widgets = {
  6. "name": forms.TextInput(attrs={"class": "form-control"}),
  7. "password": forms.PasswordInput(attrs={"class": "form-control"}),
  8. "age": forms.TextInput(attrs={"class": "form-control"}),
  9. }

重新定义的init方法,批量设置

  1. class UserModelForm(forms.ModelForm):
  2. class Meta:
  3. model = models.UserInfo
  4. fields = ["name", "password", "age",]
  5. def __init__(self, *args, **kwargs):
  6. super().__init__(*args, **kwargs)
  7. # 循环ModelForm中的所有字段,给每个字段的插件设置
  8. for name, field in self.fields.items():
  9. field.widget.attrs = {
  10. "class": "form-control",
  11. "placeholder": field.label
  12. }

自定义类

  1. class BootStrapModelForm(forms.ModelForm):
  2. def __init__(self, *args, **kwargs):
  3. super().__init__(*args, **kwargs)
  4. # 循环ModelForm中的所有字段,给每个字段的插件设置
  5. for name, field in self.fields.items():
  6. # 字段中有属性,保留原来的属性,没有属性,才增加。
  7. if field.widget.attrs:
  8. field.widget.attrs["class"] = "form-control"
  9. field.widget.attrs["placeholder"] = field.label
  10. else:
  11. field.widget.attrs = {
  12. "class": "form-control",
  13. "placeholder": field.label
  14. }

筛选操作(ORM)

整理的所有ORM操作:
https://www.cnblogs.com/wupeiqi/articles/6216618.html

  1. models.PrettyNum.objects.filter(mobile="19999999991",id=12)
  2. data_dict = {"mobile":"19999999991","id":123}
  3. models.PrettyNum.objects.filter(**data_dict)
  1. models.PrettyNum.objects.filter(id=12) # 等于12
  2. models.PrettyNum.objects.filter(id__gt=12) # 大于12
  3. models.PrettyNum.objects.filter(id__gte=12) # 大于等于12
  4. models.PrettyNum.objects.filter(id__lt=12) # 小于12
  5. models.PrettyNum.objects.filter(id__lte=12) # 小于等于12
  6. data_dict = {"id__lte":12}
  7. models.PrettyNum.objects.filter(**data_dict)
  1. models.PrettyNum.objects.filter(mobile="999") # 等于
  2. models.PrettyNum.objects.filter(mobile__startswith="1999") # 筛选出以1999开头
  3. models.PrettyNum.objects.filter(mobile__endswith="999") # 筛选出以999结尾
  4. models.PrettyNum.objects.filter(mobile__contains="999") # 筛选出包含999
  5. data_dict = {"mobile__contains":"999"}
  6. models.PrettyNum.objects.filter(**data_dict)

生成图片验证码(自制)

  1. pip install pillow
  1. import random
  2. from PIL import Image, ImageDraw, ImageFont, ImageFilter
  3. def check_code(width=120, height=30, char_length=5, font_file='Monaco.ttf', font_size=28):
  4. code = []
  5. img = Image.new(mode='RGB', size=(width, height), color=(255, 255, 255))
  6. draw = ImageDraw.Draw(img, mode='RGB')
  7. def rndChar():
  8. """
  9. 生成随机字母
  10. :return:
  11. """
  12. return chr(random.randint(65, 90))
  13. def rndColor():
  14. """
  15. 生成随机颜色
  16. :return:
  17. """
  18. return (random.randint(0, 255), random.randint(10, 255), random.randint(64, 255))
  19. # 写文字
  20. font = ImageFont.truetype(font_file, font_size)
  21. for i in range(char_length):
  22. char = rndChar()
  23. code.append(char)
  24. h = random.randint(0, 4)
  25. draw.text([i * width / char_length, h], char, font=font, fill=rndColor())
  26. # 写干扰点
  27. for i in range(40):
  28. draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
  29. # 写干扰圆圈
  30. for i in range(40):
  31. draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
  32. x = random.randint(0, width)
  33. y = random.randint(0, height)
  34. draw.arc((x, y, x + 4, y + 4), 0, 90, fill=rndColor())
  35. # 画干扰线
  36. for i in range(5):
  37. x1 = random.randint(0, width)
  38. y1 = random.randint(0, height)
  39. x2 = random.randint(0, width)
  40. y2 = random.randint(0, height)
  41. draw.line((x1, y1, x2, y2), fill=rndColor())
  42. img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
  43. return img, ''.join(code)
  44. if __name__ == '__main__':
  45. img, code_str = check_code()
  46. print(code_str)
  47. with open('code.png', 'wb') as f:
  48. img.save(f, format='png')

可视化图表

  • highchart,国外。
  • echarts,国内。

更多参考文档:https://echarts.apache.org/handbook/zh/get-started

文件上传

基本操作

  1. <form method="post" enctype="multipart/form-data">
  2. {% csrf_token %}
  3. <input type="text" name="username">
  4. <input type="file" name="avatar">
  5. <input type="submit" value="提交">
  6. </form>
  1. from django.shortcuts import render, HttpResponse
  2. def upload_list(request):
  3. if request.method == "GET":
  4. return render(request, 'upload_list.html')
  5. # # 'username': ['big666']
  6. # print(request.POST) # 请求体中数据
  7. # # {'avatar': [<InMemoryUploadedFile: 图片 1.png (image/png)>]}>
  8. # print(request.FILES) # 请求发过来的文件 {}
  9. file_object = request.FILES.get("avatar")
  10. # print(file_object.name) # 文件名:WX20211117-222041@2x.png
  11. f = open(file_object.name, mode='wb')
  12. for chunk in file_object.chunks():
  13. f.write(chunk)
  14. f.close()
  15. return HttpResponse("...")

案例:批量上传数据

  1. <form method="post" enctype="multipart/form-data" action="/depart/multi/">
  2. {% csrf_token %}
  3. <div class="form-group">
  4. <input type="file" name="exc">
  5. </div>
  6. <input type="submit" value="上传" class="btn btn-info btn-sm">
  7. </form>
  1. def depart_multi(request):
  2. """ 批量删除(Excel文件)"""
  3. from openpyxl import load_workbook
  4. # 1.获取用户上传的文件对象
  5. file_object = request.FILES.get("exc")
  6. # 2.对象传递给openpyxl,由openpyxl读取文件的内容
  7. wb = load_workbook(file_object)
  8. sheet = wb.worksheets[0]
  9. # 3.循环获取每一行数据
  10. for row in sheet.iter_rows(min_row=2):
  11. text = row[0].value
  12. exists = models.Department.objects.filter(title=text).exists()
  13. if not exists:
  14. models.Department.objects.create(title=text)
  15. return redirect('/depart/list/')

案例:混合数据(Form)

提交页面时:用户输入数据 + 文件(输入不能为空、报错)。

  • Form生成HTML标签:type=file
  • 表单的验证
  • form.cleaned_data 获取 数据 + 文件对象 ```html {% extends ‘layout.html’ %}

{% block content %}

  1. <div class="container">
  2. <div class="panel panel-default">
  3. <div class="panel-heading">
  4. <h3 class="panel-title"> {{ title }} </h3>
  5. </div>
  6. <div class="panel-body">
  7. <form method="post" enctype="multipart/form-data" novalidate >
  8. {% csrf_token %}
  9. {% for field in form %}
  10. <div class="form-group">
  11. <label>{{ field.label }}</label>
  12. {{ field }}
  13. <span style="color: red;">{{ field.errors.0 }}</span>
  14. </div>
  15. {% endfor %}
  16. <button type="submit" class="btn btn-primary">提 交</button>
  17. </form>
  18. </div>
  19. </div>
  20. </div>

{% endblock %}

  1. ```python
  2. from django import forms
  3. from app01.utils.bootstrap import BootStrapForm
  4. class UpForm(BootStrapForm):
  5. bootstrap_exclude_fields = ['img']
  6. name = forms.CharField(label="姓名")
  7. age = forms.IntegerField(label="年龄")
  8. img = forms.FileField(label="头像")
  9. def upload_form(request):
  10. title = "Form上传"
  11. if request.method == "GET":
  12. form = UpForm()
  13. return render(request, 'upload_form.html', {"form": form, "title": title})
  14. form = UpForm(data=request.POST, files=request.FILES)
  15. if form.is_valid():
  16. # {'name': '武沛齐', 'age': 123, 'img': <InMemoryUploadedFile: 图片 1.png (image/png)>}
  17. # 1.读取图片内容,写入到文件夹中并获取文件的路径。
  18. image_object = form.cleaned_data.get("img")
  19. # file_path = "app01/static/img/{}".format(image_object.name)
  20. db_file_path = os.path.join("static", "img", image_object.name)
  21. file_path = os.path.join("app01", db_file_path)
  22. f = open(file_path, mode='wb')
  23. for chunk in image_object.chunks():
  24. f.write(chunk)
  25. f.close()
  26. # 2.将图片文件路径写入到数据库
  27. models.Boss.objects.create(
  28. name=form.cleaned_data['name'],
  29. age=form.cleaned_data['age'],
  30. img=db_file_path,
  31. )
  32. return HttpResponse("...")
  33. return render(request, 'upload_form.html', {"form": form, "title": title})

注意:就目前而言,所有的静态文件都只能放在static目录。
在django的开发过程中两个特殊的文件夹:

  • static,存放静态文件的路径,包括:CSS、JS、项目图片。
  • media,用户上传的数据的目录。

    启用media

    在urls.py中进行配置: ``` from django.urls import path, re_path from django.views.static import serve from django.conf import settings

urlpatterns = [ re_path(r’^media/(?P.*)$’, serve, {‘document_root’: settings.MEDIA_ROOT}, name=’media’), ]

  1. settings.py中进行配置:

import os

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

  1. 在浏览器上访问这个地址:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/27533671/1658409131502-d23e96fa-1715-4fab-be7a-c9e63b721cbb.png#averageHue=%23dadddd&clientId=ua7a0a697-631d-4&from=paste&height=251&id=ue1607a63&originHeight=414&originWidth=1201&originalType=binary&ratio=1&rotation=0&showTitle=false&size=188921&status=done&style=none&taskId=u5daadf25-605d-40c6-b9a6-c85c352c016&title=&width=727.8787458085294)
  2. <a name="34486692"></a>
  3. ### 案例:混合数据(form)
  4. ```python
  5. from django import forms
  6. from app01.utils.bootstrap import BootStrapForm
  7. class UpForm(BootStrapForm):
  8. bootstrap_exclude_fields = ['img']
  9. name = forms.CharField(label="姓名")
  10. age = forms.IntegerField(label="年龄")
  11. img = forms.FileField(label="头像")
  12. def upload_form(request):
  13. title = "Form上传"
  14. if request.method == "GET":
  15. form = UpForm()
  16. return render(request, 'upload_form.html', {"form": form, "title": title})
  17. form = UpForm(data=request.POST, files=request.FILES)
  18. if form.is_valid():
  19. # {'name': '武沛齐', 'age': 123, 'img': <InMemoryUploadedFile: 图片 1.png (image/png)>}
  20. # 1.读取图片内容,写入到文件夹中并获取文件的路径。
  21. image_object = form.cleaned_data.get("img")
  22. # media_path = os.path.join(settings.MEDIA_ROOT, image_object.name)
  23. media_path = os.path.join("media", image_object.name)
  24. f = open(media_path, mode='wb')
  25. for chunk in image_object.chunks():
  26. f.write(chunk)
  27. f.close()
  28. # 2.将图片文件路径写入到数据库
  29. models.Boss.objects.create(
  30. name=form.cleaned_data['name'],
  31. age=form.cleaned_data['age'],
  32. img=media_path,
  33. )
  34. return HttpResponse("...")
  35. return render(request, 'upload_form.html', {"form": form, "title": title})

案例:混合数据(ModalForm)

models.py

  1. class City(models.Model):
  2. """ 城市 """
  3. name = models.CharField(verbose_name="名称", max_length=32)
  4. count = models.IntegerField(verbose_name="人口")
  5. # 本质上数据库也是CharField,自动保存数据。
  6. img = models.FileField(verbose_name="Logo", max_length=128, upload_to='city/')

定义ModelForm

  1. from app01.utils.bootstrap import BootStrapModelForm
  2. class UpModelForm(BootStrapModelForm):
  3. bootstrap_exclude_fields = ['img']
  4. class Meta:
  5. model = models.City
  6. fields = "__all__"

视图

  1. def upload_modal_form(request):
  2. """ 上传文件和数据(modelForm)"""
  3. title = "ModelForm上传文件"
  4. if request.method == "GET":
  5. form = UpModelForm()
  6. return render(request, 'upload_form.html', {"form": form, 'title': title})
  7. form = UpModelForm(data=request.POST, files=request.FILES)
  8. if form.is_valid():
  9. # 对于文件:自动保存;
  10. # 字段 + 上传路径写入到数据库
  11. form.save()
  12. return HttpResponse("成功")
  13. return render(request, 'upload_form.html', {"form": form, 'title': title})

小结

  • 自己手动去写
    1. file_object = request.FILES.get("exc")
    2. ...
  • Form组件(表单验证) ```python request.POST file_object = request.FILES.get(“exc”)

具体文件操作还是手动自己做。

  1. - ModelForm(表单验证 + 自动保存数据库 + 自动保存文件)
  • Media文件夹
  • Models.py定义类文件要 img = models.FileField(verbose_name=”Logo”, max_length=128, upload_to=’city/‘) ```

知识点

中间件

image.png
在中间件的process_request方法

  • 如果方法中没有返回值(返回None),继续向后走
  • 如果有返回值 HttpResponse、render 、redirect,则不再继续向后执行。

    定义中间件

    ```python from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse

class M1(MiddlewareMixin): “”” 中间件1 “””

  1. def process_request(self, request):
  2. # 如果方法中没有返回值(返回None),继续向后走
  3. # 如果有返回值 HttpResponse、render 、redirect
  4. print("M1.process_request")
  5. return HttpResponse("无权访问")
  6. def process_response(self, request, response):
  7. print("M1.process_response")
  8. return response

class M2(MiddlewareMixin): “”” 中间件2 “””

  1. def process_request(self, request):
  2. print("M2.process_request")
  3. def process_response(self, request, response):
  4. print("M2.process_response")
  5. return response
  1. <a name="wf333"></a>
  2. #### 应用中间件 setings.py
  3. ```python
  4. MIDDLEWARE = [
  5. 'django.middleware.security.SecurityMiddleware',
  6. 'django.contrib.sessions.middleware.SessionMiddleware',
  7. 'django.middleware.common.CommonMiddleware',
  8. 'django.middleware.csrf.CsrfViewMiddleware',
  9. 'django.contrib.auth.middleware.AuthenticationMiddleware',
  10. 'django.contrib.messages.middleware.MessageMiddleware',
  11. 'django.middleware.clickjacking.XFrameOptionsMiddleware',
  12. 'app01.middleware.auth.M1',
  13. 'app01.middleware.auth.M2',
  14. ]

登录(Cookie和Session)

登录成功后:
Cookie和Session,用户登录信息保存起来。

  • cookie,随机字符串
  • session,用户信息

在其他需要登录才能访问的页面中,都需要加入:

  1. def index(request):
  2. info = request.session.get("info")
  3. if not info:
  4. return redirect('/login/')
  5. ...

目标:在18个视图函数前面统一加入判断。

  1. info = request.session.get("info")
  2. if not info:
  3. return redirect('/login/')

对 HttpResponse()对象的set_cookie方法进行设置 HttpResponse().set_cookie()
第一个参数是 键名 第二参数是对应的值
参数 max_age 设置过期时间,单位是秒
参数 expires 设置到那个时间过期 日期类型

  1. # 编写视图函数,进行设置
  2. from datetime import datetime,timedelta
  3. def set_cookie(request):
  4. """设置cookie"""
  5. response = HttpResponse("设置cookie")
  6. ''' max_age 设置过期时间,单位是秒 '''
  7. # response.set_cookie('name', 'tong', max_age=14 * 24 * 3600)
  8. ''' expires 设置过期时间,是从现在的时间开始到那个时间结束 '''
  9. response.set_cookie('name', 'tong', expires=datetime.now()+timedelta(days=14))
  10. return response

获取cookie
利用request的request.COOKIES[‘键名’] 来获取cookie

  1. # 视图函数中定义 get_cookie 方法
  2. def get_cookie(request):
  3. """获取cookie"""
  4. name = request.COOKIES['name']
  5. return HttpResponse(name)

Session

使用重定向如果要传数据的话 可以用session来传输
request.session[‘key_name] = value

  1. request.session['msg'] = u'用户未登录'

然后在模板中使用:

  1. <h2>{{ request.session.username }}</h2> {# 输出username保存的值 #}
  2. {# {{ request.session['username' }} 以及{{ request.session.get('username') }} 和{% request.session.get('username') %} 都是错误的写法 #}}

补充知识:在django中,redirect如何传递message。
在django中,默认的message,只能在同一个request中传递。
但如果在请求过程中,使用了redirect跳转,那么,这个一次性的message就会失败,
无法在前端给用户提示。
网上提供的思路,有如下两种:
一,使用message框架中的storeage存储实现。我觉得如果消息使用得频繁,且消息比较长时使用。
二,使用session来实现,这个实现更简单,但不可太频繁使用。
下面,就使用第二种来试试吧。
1,在有redirect的view中,加入session。

  1. # 跨request传递message,使用session。
  2. self.request.session['create_app'] = name
  3. return redirect(reverse_lazy('app:list', args=()))

2,在需要获取message的view中,加入消息。

  1. # 获取创建组件成功的session提示,同request传递message。
  2. create_app = self.request.session.pop('create_app', False)
  3. if create_app:
  4. messages.info(self.request, '{}创建成功,请编辑它的配置!'.format(create_app))

3,在前端网页中,显示此message。

  1. {% for message in messages %}
  2. <div class="alert alert-success alert-dismissible fade in" role="alert">
  3. <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  4. <span aria-hidden="true">×</span>
  5. </button>
  6. <strong>组件创建提示!</strong> {{ message }}.
  7. </div>
  8. {% endfor %}

注销

  1. def logout(request):
  2. rep = redirect('/login/')
  3. rep.delete_cookie("is_login")
  4. return rep # 点击注销后执行,删除cookie,不再保存用户状态,并弹到登录页面
  1. def logout(request):
  2. """ 注销 """
  3. request.session.clear()
  4. return redirect('/login/')

Ajax请求

浏览器向网站发送请求时:URL 和 表单的形式提交。

  • GET
  • POST

特点:页面刷新。
除此之外,也可以基于Ajax向后台发送请求(偷偷的发送请求)。

  • 依赖jQuery
  • 编写ajax代码
    1. $.ajax({
    2. url:"发送的地址",
    3. type:"get",
    4. data:{
    5. n1:123,
    6. n2:456
    7. },
    8. success:function(res){
    9. console.log(res);
    10. }
    11. })

    GET请求

    1. $.ajax({
    2. url: '/task/ajax/',
    3. type: "get",
    4. data: {
    5. n1: 123,
    6. n2: 456
    7. },
    8. success: function (res) {
    9. console.log(res);
    10. }
    11. })
    ```python from django.shortcuts import render, HttpResponse

def task_ajax(request): print(request.GET) return HttpResponse(“成功了”)

  1. <a name="IuRHA"></a>
  2. #### POST请求
  3. ```css
  4. <form action='{% url 'LOGIN' %}' method="post">
  5. {% csrf_token %} {# 增加验证,是否是通过get请求先访问页面,然后再进行的提交,否则无法直接提交 #}
  6. 用户名<input type="text" name="username">
  7. 密码<input type="password" name="pwd">
  8. <br>
  9. <input type="submit" value="登录">
  10. </form>
  1. $.ajax({
  2. url: '/task/ajax/',
  3. type: "get",
  4. data: {
  5. n1: 123,
  6. n2: 456
  7. },
  8. success: function (res) {
  9. console.log(res);
  10. }
  11. })
  1. from django.shortcuts import render, HttpResponse
  2. from django.views.decorators.csrf import csrf_exempt
  3. @csrf_exempt
  4. def task_ajax(request):
  5. print(request.GET)
  6. print(request.POST)
  7. return HttpResponse("成功了")

关闭绑定事件

  1. {% extends 'layout.html' %}
  2. {% block content %}
  3. <div class="container">
  4. <h1>任务管理</h1>
  5. <h3>示例1</h3>
  6. <input id="btn1" type="button" class="btn btn-primary" value="点击"/>
  7. </div>
  8. {% endblock %}
  9. {% block js %}
  10. <script type="text/javascript">
  11. $(function () {
  12. // 页面框架加载完成之后代码自动执行
  13. bindBtn1Event();
  14. })
  15. function bindBtn1Event() {
  16. $("#btn1").click(function () {
  17. $.ajax({
  18. url: '/task/ajax/',
  19. type: "post",
  20. data: {
  21. n1: 123,
  22. n2: 456
  23. },
  24. success: function (res) {
  25. console.log(res);
  26. }
  27. })
  28. })
  29. }
  30. </script>
  31. {% endblock %}

ajax请求的返回值

一般都会返回JSON格式。

  1. {% extends 'layout.html' %}
  2. {% block content %}
  3. <div class="container">
  4. <h1>任务管理</h1>
  5. <h3>示例1</h3>
  6. <input id="btn1" type="button" class="btn btn-primary" value="点击"/>
  7. </div>
  8. {% endblock %}
  9. {% block js %}
  10. <script type="text/javascript">
  11. $(function () {
  12. // 页面框架加载完成之后代码自动执行
  13. bindBtn1Event();
  14. })
  15. function bindBtn1Event() {
  16. $("#btn1").click(function () {
  17. $.ajax({
  18. url: '/task/ajax/',
  19. type: "post",
  20. data: {
  21. n1: 123,
  22. n2: 456
  23. },
  24. dataType: "JSON",
  25. success: function (res) {
  26. console.log(res);
  27. console.log(res.status);
  28. console.log(res.data);
  29. }
  30. })
  31. })
  32. }
  33. </script>
  34. {% endblock %}
  1. import json
  2. from django.shortcuts import render, HttpResponse
  3. from django.http import JsonResponse
  4. from django.views.decorators.csrf import csrf_exempt
  5. def task_list(request):
  6. """ 任务列表 """
  7. return render(request, "task_list.html")
  8. @csrf_exempt
  9. def task_ajax(request):
  10. print(request.GET)
  11. print(request.POST)
  12. data_dict = {"status": True, 'data': [11, 22, 33, 44]}
  13. return HttpResponse(json.dumps(data_dict))

模块

  • 分类 ```
  • 自定义模块:自己写文件/文件夹
  • 内置模块:time/datetime/json/hashlib/random/re等
  • 第三方模块:openpyxl/requests/bs4/flask/django等 ```

  • 自定义模块 ```

  • sys.path,Python内部导入模块时,根据目录去寻找。
  • 一定不要让自己写的模块名和内置的模块名重复(*
  • 导入模块: import xxx from xxx import xxx ```

  • 内置模块 ```

  • 时间部分:time/datetime/字符串类型。
  • random:随机生成数字。
  • hashlib:加密(md5加密、md5加密+加盐) 防止被撞库。
  • json:
    • JSON格式的字符串: 内部字符串双引号、内部[]
    • json.dumps
    • json.loads
  • re和正则

    • 正则:\d \w ; 贪婪匹配。
    • re.search/re.match/ re.findall ```
  • 第三方模块 ```

  • 安装第三方模块:pip、源码、wheel
  • 常见第三方模块:
    • requests
    • bs4
    • openpyxl
    • python-docx
    • flask/django (flask简洁(轻量级);django功能强大) ```

      SQL防注入问题

      当使用Python代码去操作MySQL时,一定要防止SQL注入的问题。 ```python

      SQL语句不要用字符串格式化去拼接。

import pymysql

1.连接MySQL

conn = pymysql.connect(host=”127.0.0.1”, port=3306, user=’root’, passwd=”root123”, charset=’utf8’, db=’unicom’) cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

【错误】不要这么写

sql = “select * from admin where id > %s”.format(2) cursor.execute(sql)

【正确】这么写

cursor.execute(“select * from admin where id > %s”, [2, ])

获取符合条件的第一条数据,字典 None

res = cursor.fetchone() print(res) # {‘id’: 3, ‘username’: ‘集宁’, ‘password’: ‘qwe123’, ‘mobile’: ‘1999999999’}

3.关闭连接

cursor.close() conn.close()

  1. <a name="1349b522"></a>
  2. ### 前端开发
  3. <a name="jrrYi"></a>
  4. #### HTML
  • 块级和行内标签(div、span) 块级:div/h系列 行内:span/a (设置高度、宽度、边距无效)
  • Form表单

  • 关于a标签 百度 超链接去跳转。 做锚点

    1. <a href="#m1">第一章</a>
    2. <a href="#m2">第二章</a>
    3. <div id="m1" style="height: 1000px;">第一章 谢新雪</div>
    4. <div id="m2" style="height: 1000px;">第二章 单独的</div>

    ```

CSS

  1. - 位置
  2. - 标签 <div style="xxx">
  3. - style代码块
  4. <style>
  5. div { }
  6. #v1 { }
  7. .v2 {}
  8. </style>
  9. - 文件中
  10. - 选择器
  11. div { }
  12. #v1 { }
  13. .v2 { }
  14. div[xx='11'] { }
  15. - 样式
  16. color;fonts-ize; background-color; padding; margin;
  17. float:left; ,脱离文档流。 clear:both; :after

JavaScript & jQuery

  1. - 本质上:找到标签;操作标签。
  2. - 找标签
  3. $("#x1")
  4. $(".x1")
  5. $("div")
  6. $("input[type='text']") 找到 input 标签且 type='text'
  7. - 操作标签
  8. $("#x1").text() <div id='x1'>dd</div>
  9. $("#x1").text("xxx") <div id='x1'>xxx</div>
  10. $("#x1").val() <input id='x1' />
  11. $("#x1").val("xxx") <input id='x1' />
  12. $("#x1").attr("uu") <div id='x1' uu="123">dd</div>
  13. $("#x1").attr("uu","999") <div id='x1' uu="999">dd</div>
  14. $("#x1").empty() <div id='x1'>dd</div> - 清空内容
  15. $("#x1").remove() <div id='x1'>dd</div> - 整个标签删除

BootStrap

  1. - 支持响应式布局,根据屏幕的宽度调整布局。
  2. - 栅格,12份。
  3. - 常见的样式:
  4. - container / container-fluid
  5. - 面板
  6. - 按钮
  7. - 表单
  8. - 表格
  9. - 对话框

第三方插件

  1. - 插件一般都包含:CSSJavaScript,开发使用时候
  2. - 引入cssjs(依赖jQuery
  3. - 使用

关于注释

  1. - Python语言
  2. # 注释
  3. """ 注释 """
  4. - HTML
  5. <!-- -->
  6. - CSS注释
  7. /* 注释 */
  8. - JavaScript
  9. // 注释
  10. /* 注释 */

总结

F和Q

更多

关于django的开发知识点,更多的案例:

不建议小白学(协程)

https://www.bilibili.com/video/BV1NA411g7yf?spm_id_from=333.999.0.0

  1. - MySQL数据库
  2. ```python
  3. # 2021最新推荐
  4. https://www.bilibili.com/video/BV15R4y1b7y9?spm_id_from=333.999.0.0
  5. # 2017年
  6. https://www.bilibili.com/video/BV1DE411n7fU?
  • 前端开发
    1. https://www.bilibili.com/video/BV1QE411j7bV?spm_id_from=333.999.0.0
  • django开发知识点
    1. https://www.bilibili.com/video/BV1zE411x7LG
    2. https://www.bilibili.com/video/BV1JE411V7xk
  • 项目开发
    1. 任务管理平台:https://www.bilibili.com/video/BV1uA411b77M
  • 进阶项目(增删改查、权限)
    1. https://space.bilibili.com/283478842/channel/detail?cid=91596&ctype=0
  • git 版本控制和协同开发 + 任务管理平台
    1. https://www.bilibili.com/video/BV19E411f76x?spm_id_from=333.999.0.0
  • 微信小程序 + Django + drf框架编写
    1. https://www.bilibili.com/video/BV1jC4y1s7QD?spm_id_from=333.999.0.0