- 创建项目
- 创建APP
- 创建templates文件夹
- 设置数据库为mysql
- 模板的继承
- 初识Form
- ModelForm(推荐)
- form/modelform设置样式
- modelform设置填充数据
- 校验和保存数据
- 后台管理系统配置设置
- 关闭DEBUG模式:
- 添加simpleui、导入导出应用
- 注意:这里一定要把simpleui放在最前面
- 默认首页设置
- SIMPLEUI_LOGO = ‘xxx’ # 可选添加,换成自己Logo链接
- 设置语言、时区
- collectstatic静态资源路径设置
- 一些 小tip !!!!!!!
- 文件上传
- 知识点
- SQL语句不要用字符串格式化去拼接。
- 1.连接MySQL
- 【错误】不要这么写
- 【正确】这么写
- 获取符合条件的第一条数据,字典 None
- 3.关闭连接
- 总结
- 不建议小白学(协程)
创建项目
django-admin startproject 项目名称
创建APP
python manage.py startapp 程序名称
注册APP【settings.py】
编写url与视图函数的对应关系
- 在 urls.py ,路由 ( URL 和 函数的对应关系)。
在urls.py文件中导入views
编写对应关系
编写视图函数
- 在views.py,视图函数,编写业务逻辑。
在views.py中导入HttpResponse
编写对应的函数
- 视图函数
默认参数request,包含请求相关的所有数据。
request.method
request.GET
request.POST
request.FILES,上传文件。
request.path_info,获取当前请求的URL
http://127.0.0.1:8000/depart/add/ -> /depart/add/
def admin_list(request):
k1 = request.POST.get("k1")
... 业务处理
return 数据
- 默认参数request,包含请求相关的所有数据。
request.method
request.GET
request.POST
request.FILES,上传文件。
request.path_info,获取当前请求的URL
http://127.0.0.1:8000/depart/add/ -> /depart/add/
- 返回值
return HttpResponse("字符串")
return JSONResponse( {"status":123,"data":[456,55,66,22,]} )
return JSONResponse( [11,22,33,44] ,safe=False)
return render(request,"xxx.html",{值})
return redirect("http://127.0.0.1:8000/depart/add/")
return redirect("/depart/add/")
启动django项目
python manage.py runserver
创建templates文件夹
创建静态文件夹
引用静态文件
设置数据库为mysql
安装第三方模块
django连接数据库
在settings.py文件中进行配置和修改。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'gx_day15', # 数据库名字
'USER': 'root',
'PASSWORD': 'root123',
'HOST': '127.0.0.1', # 那台机器安装了MySQL
'PORT': 3306,
}
}
根据迁移文件去创建数据库表结构
python manage.py migrate
关闭重连数据库,查看
从数据库导出生成models.py,在lms目录下得到models.py
python manage.py inspectdb > models.py
将导出的models.py文件替换原有的app内的文件
生成迁移文件
python manage.py makemigrations 程序名称
根据迁移文件去创建数据库表结构
模板的继承
templates目录,编写HTML模板(含有模板语法、继承、{% static ‘xx’%})
定义模板:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'plugin...min.css' %}">
{% block css %}{% endblock %}
</head>
<body>
<h1>标题</h1>
<div>
{% block content %}{% endblock %}
</div>
<h1>底部</h1>
<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
{% block js %}{% endblock %}
</body>
</html>
继承模板:
{% extends 'layout.html' %}
{% block css %}
<link rel="stylesheet" href="{% static 'pluxxx.css' %}">
<style>
...
</style>
{% endblock %}
{% block content %}
<h1>首页</h1>
{% endblock %}
{% block js %}
<script src="{% static 'js/jqxxxin.js' %}"></script>
{% 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})
<a name="2.user_add.html"></a>
#### 2.user_add.html
```html
<form method="post">
{% for field in form%}
{{ field }}
{% endfor %}
<!-- <input type="text" placeholder="姓名" name="user" /> -->
</form>
<form method="post">
{{ form.user }}
{{ form.pwd }}
{{ form.email }}
<!-- <input type="text" placeholder="姓名" name="user" /> -->
</form>
ModelForm(推荐)
from django.forms import ModelForm
from app01 import models
0. models.py
class UserInfo(models.Model):
""" 员工表 """
name = models.CharField(verbose_name="姓名", max_length=16)
password = models.CharField(verbose_name="密码", max_length=64)
age = models.IntegerField(verbose_name="年龄")
account = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0)
create_time = models.DateTimeField(verbose_name="入职时间")
depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)
gender_choices = (
(1, "男"),
(2, "女"),
)
gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
1. views.py
class MyForm(ModelForm):
xx = form.CharField*("...")
class Meta:
model = UserInfo
fields = ["name","password","age","xx"]
def user_add(request):
if request.method == "GET":
form = MyForm()
return render(request, 'user_add.html',{"form":form})
2.user_add.html
<form method="post">
{% for field in form%}
{{ field }}
{% endfor %}
<!-- <input type="text" placeholder="姓名" name="user" /> -->
</form>
<form method="post">
{{ form.user }}
{{ form.pwd }}
{{ form.email }}
<!-- <input type="text" placeholder="姓名" name="user" /> -->
</form>
form/modelform设置样式
modelform设置填充数据
校验和保存数据
- 通过 form = DetailForm(data=request.POST) 接收用户提交的数据
- 通过 form.is_valid() 进行校验
- 通过 form.save() 保存数据
- 如果没通过校验,返回当前页面及当前的form对象,其包含错误信息
html设置:def edittest(request, nid):
# 获取填充的数据
row_object = models.Detail.objects.filter(id=nid).first()
if request.method == "GET":
form = DetailForm(instance=row_object)
return render(request, 'edittest.html', {'form': form})
# 提交用户的请求
form = DetailForm(data=request.POST, instance=row_object)
# 进行校验
if form.is_valid():
# 保存数据
form.save()
return redirect('/test/show')
print('error')
return render(request, "edittest.html", {'form': form}) # 包含错误信息
后台管理系统配置设置
配置文件
lms/lms/settings.py ```python关闭DEBUG模式:
DEBUG = False # 修改
ALLOWED_HOSTS = [‘*’, ] # 修改
添加simpleui、导入导出应用
INSTALLED_APPS = [
注意:这里一定要把simpleui放在最前面
'simpleui', # 添加
'import_export', # 添加
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'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’ # 添加
<a name="QdeN8"></a>
### 迁移静态文件
```shell
python manage.py collectstatic
执行成功后,会在manage.py相同路径下创建static文件夹
系统标题设置
lms/lms/urls.py
from django.contrib import admin
from django.urls import path
from django.views import static
from django.conf import settings
from django.urls import include, re_path
admin.site.site_header = '左上角和登录页'
admin.site.site_title = '我在浏览器标签'
admin.site.index_title = '我在后台首页'
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^static/(?P<path>.*)$', static.serve,
{'document_root': settings.STATIC_ROOT}, name='static'),
]
启动项目
初始化数据库
python manage.py migrate
创建超级管理员
# 首先,我们得创建一个能登录管理页面的用户。
python manage.py createsuperuser
# 输入你想要使用的用户名,然后按下回车键:
Username: admin
# 然后输入想要使用的邮件地址:
Email address: admin@example.com
# 最后一步是输入密码。你会被要求输入两次密码,第二次的目的是为了确认第一次输入的确实是你想要的密码。
Password: **********
Password (again): *********
Superuser created successfully.
启动项目
python manage.py runserver 8000
浏览器打开127.0.0.1:8000/admin,输入账号密码,进入系统
将应用注册到管理页面
lms/library/admin.py
from django.contrib import admin
from .models import Detail # 增加
# Register your models here.
admin.site.register(Detail) # 增加
配置菜单中文名
lms/library/apps.py
class App01Config(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'app01'
verbose_name = "试题管理" # 添加
lms/library/models.py
class Detail(models.Model):
id = models.CharField(primary_key=True, max_length=255,
auto_created=True, blank=False, verbose_name='编号')
title = models.TextField(blank=True, null=True, verbose_name='题目')
a = models.TextField(blank=True, null=True,verbose_name='选项A')
b = models.TextField(blank=True, null=True,verbose_name='选项B')
c = models.TextField(blank=True, null=True,verbose_name='选项C')
d = models.TextField(blank=True, null=True,verbose_name='选项D')
class Meta:
managed = False
db_table = 'detail'
verbose_name = "试题详情管理" # 增加
verbose_name_plural = "试题详情" # 增加
'''
class Book(models.Model):
name = models.CharField(max_length=50, db_collation='utf8_general_ci', verbose_name = '书名')
price = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True, verbose_name = '价格')
author = models.CharField(max_length=50, db_collation='utf8_general_ci', blank=True, null=True, verbose_name = '作者')
library = models.ForeignKey('Library', models.DO_NOTHING, blank=True, null=True, verbose_name = '存放仓库')
num = models.PositiveIntegerField(blank=True, null=True, verbose_name = '数量')
class Meta:
managed = True
db_table = 'book'
verbose_name = "书籍管理"
verbose_name_plural = "书籍管理"
'''
页面字段显示设置
stgl/app01/admin.py
from django.contrib import admin
from .models import Detail # 增加
class DetailAdmin(admin.ModelAdmin): # 增加
list_display = ['id','title','a','b','c','d'] # 增加
admin.site.register(Detail,DetailAdmin)
字段中文名设置
lms/library/models.py
class Book(models.Model):
name = models.CharField(max_length=50, db_collation='utf8_general_ci')
price = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
author = models.CharField(max_length=50, db_collation='utf8_general_ci', blank=True, null=True)
library = models.ForeignKey('Library', models.DO_NOTHING, blank=True, null=True)
num = models.PositiveIntegerField(blank=True, null=True)
class Meta:
managed = True
db_table = 'book'
verbose_name = "书籍管理"
verbose_name_plural = "书籍管理"
增加搜索功能
stgl/app01/admin.py
from django.contrib import admin
from .models import Book
class BookAdmin(admin.ModelAdmin):
list_display = ['name','price','author','library','num']
list_filter = ['name','author','price'] # 增加 过滤器
admin.site.register(Book,BookAdmin) # 修改
增加导入导出功能
新建lms/library/resource.py
from import_export import resources
from .models import Detail
class DetailResource(resources.ModelResource):
class Meta:
model = Detail
lms/library/admin.py
from django.contrib import admin
from .models import Detail
from .resource import DetailResource # 增加
from import_export.admin import ImportExportModelAdmin,ImportMixin,ExportMixin # 增加
class DetailAdmin(ImportExportModelAdmin,admin.ModelAdmin):
list_display = ['id','title','a','b','c','d']
list_filter = ['id','title'] # 过滤器
resource_class = DetailResource # 增加
admin.site.register(Detail,DetailAdmin)
添加其他管理
配置admin.py,apps.py,models.py
# Register your models here.
from django.contrib import admin
from .models import Agreement, Invitation, InvitationInfo, Comment # 增加
from .resource import InvitationResource, AgreementResource, InvitationInfoResource, CommentResource # 增加
from import_export.admin import ImportExportModelAdmin, ImportMixin, ExportMixin # 增加
class InvitationAdmin(admin.ModelAdmin): # 增加
list_display = ['id', 'title', 'content', 'state', 'picture'] # 增加
list_filter = ['state'] # 过滤器 可根据字段类型进行筛选。
list_editable = ['state'] # 在当前页面进行编辑,无需点击字段名进入详情页编辑。
search_fields = ['title', 'content'] # 通过输入的词对title包含的字段进行筛选。
resource_class = InvitationResource # 增加
class AgreementAdmin(admin.ModelAdmin): # 增加
list_display = ['invi', 'user'] # 增加
list_filter = ['invi', 'user'] # 过滤器 可根据字段类型进行筛选。
search_fields = ['invi', 'user'] # 通过输入的词对title包含的字段进行筛选。
resource_class = AgreementResource # 增加
class CommentAdmin(admin.ModelAdmin): # 增加
list_display = ['id', 'content', 'category', 'info_id',
'user', 'time', ] # 增加
# list_filter = ['invi', 'user'] # 过滤器 可根据字段类型进行筛选。
# list_editable = ['invi', 'user'] # 在当前页面进行编辑,无需点击字段名进入详情页编辑。
# search_fields = ['invi', 'user'] # 通过输入的词对title包含的字段进行筛选。
resource_class = CommentResource # 增加
class InvitationInfoAdmin(admin.ModelAdmin): # 增加
list_display = ['invi', 'user', 'time'] # 增加
# list_filter = ['invi', 'user'] # 过滤器 可根据字段类型进行筛选。
# list_editable = ['invi', 'user'] # 在当前页面进行编辑,无需点击字段名进入详情页编辑。
# search_fields = ['invi', 'user'] # 通过输入的词对title包含的字段进行筛选。
resource_class = InvitationInfoResource # 增加
admin.site.register(Agreement, AgreementAdmin)
admin.site.register(Invitation, InvitationAdmin)
# , Comment, Agreement, InvitationInfoAdmin, CommentAdmin, AgreementAdmin
admin.site.register(InvitationInfo, InvitationInfoAdmin)
admin.site.register(Comment, CommentAdmin)
apps主要是设置应用的中文名
from django.apps import AppConfig
class CampusinfoConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'campusInfo'
verbose_name = "校园资讯" # 添加
如果需要设置导入导出功能,则需要创建文件resource.py
from import_export import resources
from .models import Agreement, Invitation, InvitationInfo, Comment
class InvitationResource(resources.ModelResource):
class Meta:
model = Invitation
class AgreementResource(resources.ModelResource):
class Meta:
model = Agreement
class CommentResource(resources.ModelResource):
class Meta:
model = Comment
class InvitationInfoResource(resources.ModelResource):
class Meta:
model = InvitationInfo
时间字段显示格式
lms/lms/settings.py
#时间格式
USE_L10N = False # 增加
DATETIME_FORMAT = 'Y-m-d H:i:s' # 增加
DATE_FORMAT = 'Y-m-d' # 增加
设置登录验证码(配置)
lms/lms/settings.py
INSTALLED_APPS = [
'simpleui',
'import_export',
'multi_captcha_admin', # 添加
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
# 验证码配置,添加
MULTI_CAPTCHA_ADMIN = {
'engine': 'simple-captcha',
}
# 验证码图片大小,添加
CAPTCHA_IMAGE_SIZE = (78, 35)
# 字符个数,添加
CAPTCHA_LENGTH = 4
# 超时,添加
CAPTCHA_TIMEOUT = 1
# 设置templates路径
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['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',
],
},
},
]
lms/lms/urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('captcha/', include('captcha.urls')), # 添加
re_path(r'^static/(?P<path>.*)$', static.serve,
{'document_root': settings.STATIC_ROOT}, name='static'),
]
在lsm/templates/admin路径下新建login.html,内容如下
<!DOCTYPE html>
{% load i18n static simpletags %}
{% get_current_language as LANGUAGE_CODE %}{% get_current_language_bidi as LANGUAGE_BIDI %}
<!--
The project use: django-simpleui
source code:
https://github.com/newpanjing/simpleui
-->
<html lang="{{ LANGUAGE_CODE|default:"en-us" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
<head>
<meta charset="UTF-8">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
{% block title %}
<title>{{ site_title }}-{% trans 'Log in' %}</title>
{% endblock %}
{% block icon %}
{# <link rel="icon" href="{% static 'admin/simpleui-x/img/favicon.png' %}">#}
{% endblock %}
{% include 'admin/includes/css-part.html' %}
{% block css %}
<link rel="stylesheet" href="{% static 'admin/simpleui-x/css/login.css' %}?_=2.1">
{% endblock %}
{% block bg %}
<style type="text/css">
.bg {
background: #f0f2f5;
background-image: url('{% static 'admin/simpleui-x/img/bg.svg' %}');
min-height: 100%;
background-repeat: no-repeat;
background-position: 50%;
background-size: 100%;
padding: 20px 0;
position: relative;
}
</style>
<style type="text/css">
#id_captcha_1{
position: absolute;
margin:0 0 0 5px; /*上右下左*/
width: 265px;
font-size: inherit;
-webkit-appearance: none;
border-radius: 4px;
border: 1px solid #DCDFE6;
box-sizing: border-box;
display: inline-block;
height: 40px;
line-height: 40px;
outline: 0;
padding: 0 15px;
transition: border-color .2s cubic-bezier(.645,.045,.355,1);
text-align: center;
}
</style>
{% endblock %}
{% block head %}
{# You can add code here. #}
{% endblock %}
</head>
<body class="bg">
{% block main %}
<div class="login-main">
{% block logo %}
<div class="logo">
{% if "SIMPLEUI_LOGO"|get_config %}
<img src="{{ "SIMPLEUI_LOGO"|get_config |safe }}">
{% else %}
<img src="{% static 'admin/simpleui-x/img/logo.png' %}">
{% endif %}
</div>
{% endblock %}
{% block header %}
<div class="header">{{ site_header }}</div>
{% endblock %}
{% block errors %}
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
<el-alert
title="{{ error }}"
type="error">
</el-alert>
{% endfor %}
{% endif %}
{% if form.errors and not form.non_field_errors %}
<p class="errornote">
{% if form.errors.items|length == 1 %}
<el-alert title="{% trans "Please correct the error below." %}" type="error"></el-alert>
{% else %}
<el-alert title="{% trans "Please correct the errors below." %}" type="error"></el-alert>
{% endif %}
</p>
{% endif %}
{% endblock %}
{% block form %}
<form class="simpleui-form" action="{{ app_path }}" method="post" id="login-form">
{% csrf_token %}
<div class="simpleui-input-inline">
<el-input prefix-icon="fas fa-user" v-model="username" name="username"
placeholder="{% trans 'username' %}" autofocus></el-input>
</div>
<div class="simpleui-input-inline">
<el-input prefix-icon="fas fa-lock" type="password" v-model="password" name="password"
@keyup.enter.native="login()"
placeholder="{% trans 'password' %}" show-password></el-input>
</div>
<div>
{{ form.captcha }}
</div>
{% url 'admin_password_reset' as password_reset_url %}
{% if password_reset_url %}
<div class="password-reset-link">
<a class="forgot-password" href="{{ password_reset_url }}">{% trans 'Forgotten your password or username?' %}</a>
</div>
{% endif %}
<div class="simpleui-input-inline login-btn">
<el-button :icon="loading?'el-icon-loading':''" @click="login()"
type="primary">{% trans 'Log in' %}</el-button>
</div>
<input type="hidden" name="next" value="{{ next }}"/>
</form>
{% endblock %}
</div>
{% endblock %}
{% include 'admin/includes/js-part.html' %}
{% block login_js %}
<script type="text/javascript" src="{% static 'admin/js/jquery.min.js' %}"></script>
<script>
$(function(){
$('img.captcha').click(function () {
$.getJSON("/captcha/refresh/", function (result) {
console.log(result);
$('img.captcha').attr('src', result['image_url']);
$('#id_captcha_0').val(result['key'])
});
});
$(document).keyup(function(event){
if(event.keyCode ==13){
$('#login-form > div.simpleui-input-inline.login-btn > button').trigger("click");
}
});
})
</script>
<script type="text/javascript" src="{% static 'admin/simpleui-x/js/login.js' %}?_=3.3"></script>
{% endblock %}
{% block particles %}
{% if 'SIMPLEUI_LOGIN_PARTICLES'|get_config != False %}
<!--
Close login page particles see link:
关闭登录页粒子动画请查看:
https://github.com/newpanjing/simpleui/blob/master/QUICK.md#关闭登录页粒子动画
-->
<style type="text/css">
#particles-js {
position: fixed;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
z-index: -1;
}
.forgot-password {
margin-top: 10px;
color: #3a8ee6;
text-decoration: none;
&:hover,
&:active,
&:focus {
color: lighten($teal, 7);
}
}
</style>
<!-- particles.js container -->
<div id="particles-js"></div>
<script type="text/javascript" src="{% static 'admin/simpleui-x/particles/particles.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/simpleui-x/particles/app.js' %}"></script>
{% endif %}
{% endblock %}
</body>
</html>
# 上述文件来自simpleui默认登录文件,添加代码说明
# lmsenv\Lib\site-packages\simpleui\templates\admin\login.html
第41到59行: 设置验证码输入框样式
第114到116行:验证码位置
第136到152行:验证码点击刷新功能
下载https://cdn.bootcdn.net/ajax/libs/jquery/3.5.0/jquery.min.js,将jquery.min.js文件放入lms/static/js下
迁移文件
python manage.py migrate
浏览器打开127.0.0.1:8000/admin,输入账号密码,进入系统
一些 小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 | 二进制数据类型 |
上传文件
file = request.FILES.get('logo')
with open("./media/"+file.name, 'wb') as f:
for i in file:
f.write(i)
print(file.name)
检查None或’’空字符串或False
return bool(form.data.get('first_name', False))
在这种情况下,如果form.data[‘first_name’]不存在,它将是return False,如果值是,None或者’’这也将return False,如果值是True或’a string’它将return True.
设置密码加密存储
工具类,可以创建一个py文件进行导入操作
from django.conf import settings
import hashlib
def md5(data_string):
obj = hashlib.md5(settings.SECRET_KEY.encode('utf-8'))
obj.update(data_string.encode('utf-8'))
return obj.hexdigest()
设置后台首页导航栏的顺序
class ForumsystemConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'forumSystem'
verbose_name = '论坛系统'
orderIndex = 2
设置语言、时区
LANGUAGE_CODE = 'zh-hans' # 修改,更改默认语言为中文
TIME_ZONE = 'Asia/Shanghai' # 修改,更改时区
USE_TZ = False # 修改
post请求设置
POST提交CSRF认证
<form method='post'>
{% csrf_token %}
...
</form>
免除csrf认证
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def order_add(request):
pass
ajax手动csrf认证
$.ajax({
url:'{% url "register" %}',java
type:'POST',
data:{
...
'csrfmiddlewaretoken', $('[name=csrfmiddlewaretoken]').val()); //手动获取csrf_token值
}
dataType:'JSON',
success:function (res) {
...
例:sex设置
gender_choices = (
(1, "男"),
(2, "女"),
)
gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
获取数据表字段名
设置数据表字段别名
数据库中表关联
from django.db import models
class Department(models.Model):
""" 部门表 """
title = models.CharField(verbose_name='标题', max_length=32)
class UserInfo(models.Model):
""" 员工表 """
# 想要允许为空 null=True, blank=True
name = models.CharField(verbose_name="姓名", max_length=16)
password = models.CharField(verbose_name="密码", max_length=64)
age = models.IntegerField(verbose_name="年龄")
account = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0)
create_time = models.DateTimeField(verbose_name="入职时间")
# 无约束
# depart_id = models.BigIntegerField(verbose_name="部门ID")
# 1.有约束
# - to,与那张表关联
# - to_field,表中的那一列关联
# 2.django自动
# - 写的depart
# - 生成数据列 depart_id
# 3.部门表被删除
# ### 3.1 级联删除
depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)
# ### 3.2 置空
# depart = models.ForeignKey(to="Department", to_field="id", null=True, blank=True, on_delete=models.SET_NULL)
# 在django中做的约束
gender_choices = (
(1, "男"),
(2, "女"),
)
gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
重定向
from django.shortcuts import redirect, render, HttpResponse
return redirect('/test/show')
时间插件
<link rel="stylesheet" href="static/plugins/bootstrap-3.4.1/css/bootstrap.css">
<link rel="stylesheet" href="static/plugins/bootstrap-datepicker/css/bootstrap-datepicker.css">
<input type="text" id="dt" class="form-control" placeholder="入职日期">
<script src="static/js/jquery-3.6.0.min.js"></script>
<script src="static/plugins/bootstrap-3.4.1/js/bootstrap.js"></script>
<script src="static/plugins/bootstrap-datepicker/js/bootstrap-datepicker.js"></script>
<script src="static/plugins/bootstrap-datepicker/locales/bootstrap-datepicker.zh-CN.min.js"></script>
<script>
$(function () {
$('#dt').datepicker({
format: 'yyyy-mm-dd',
startDate: '0',
language: "zh-CN",
autoclose: true
});
})
</script>
ModelForm和BootStrap
ModelForm可以帮助我们生成HTML标签。
class UserModelForm(forms.ModelForm):
class Meta:
model = models.UserInfo
fields = ["name", "password",]
form = UserModelForm()
定义插件
class UserModelForm(forms.ModelForm):
class Meta:
model = models.UserInfo
fields = ["name", "password",]
widgets = {
"name": forms.TextInput(attrs={"class": "form-control"}),
"password": forms.PasswordInput(attrs={"class": "form-control"}),
"age": forms.TextInput(attrs={"class": "form-control"}),
}
重新定义的init方法,批量设置
class UserModelForm(forms.ModelForm):
class Meta:
model = models.UserInfo
fields = ["name", "password", "age",]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 循环ModelForm中的所有字段,给每个字段的插件设置
for name, field in self.fields.items():
field.widget.attrs = {
"class": "form-control",
"placeholder": field.label
}
自定义类
class BootStrapModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 循环ModelForm中的所有字段,给每个字段的插件设置
for name, field in self.fields.items():
# 字段中有属性,保留原来的属性,没有属性,才增加。
if field.widget.attrs:
field.widget.attrs["class"] = "form-control"
field.widget.attrs["placeholder"] = field.label
else:
field.widget.attrs = {
"class": "form-control",
"placeholder": field.label
}
筛选操作(ORM)
整理的所有ORM操作:
https://www.cnblogs.com/wupeiqi/articles/6216618.html
models.PrettyNum.objects.filter(mobile="19999999991",id=12)
data_dict = {"mobile":"19999999991","id":123}
models.PrettyNum.objects.filter(**data_dict)
models.PrettyNum.objects.filter(id=12) # 等于12
models.PrettyNum.objects.filter(id__gt=12) # 大于12
models.PrettyNum.objects.filter(id__gte=12) # 大于等于12
models.PrettyNum.objects.filter(id__lt=12) # 小于12
models.PrettyNum.objects.filter(id__lte=12) # 小于等于12
data_dict = {"id__lte":12}
models.PrettyNum.objects.filter(**data_dict)
models.PrettyNum.objects.filter(mobile="999") # 等于
models.PrettyNum.objects.filter(mobile__startswith="1999") # 筛选出以1999开头
models.PrettyNum.objects.filter(mobile__endswith="999") # 筛选出以999结尾
models.PrettyNum.objects.filter(mobile__contains="999") # 筛选出包含999
data_dict = {"mobile__contains":"999"}
models.PrettyNum.objects.filter(**data_dict)
生成图片验证码(自制)
pip install pillow
import random
from PIL import Image, ImageDraw, ImageFont, ImageFilter
def check_code(width=120, height=30, char_length=5, font_file='Monaco.ttf', font_size=28):
code = []
img = Image.new(mode='RGB', size=(width, height), color=(255, 255, 255))
draw = ImageDraw.Draw(img, mode='RGB')
def rndChar():
"""
生成随机字母
:return:
"""
return chr(random.randint(65, 90))
def rndColor():
"""
生成随机颜色
:return:
"""
return (random.randint(0, 255), random.randint(10, 255), random.randint(64, 255))
# 写文字
font = ImageFont.truetype(font_file, font_size)
for i in range(char_length):
char = rndChar()
code.append(char)
h = random.randint(0, 4)
draw.text([i * width / char_length, h], char, font=font, fill=rndColor())
# 写干扰点
for i in range(40):
draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
# 写干扰圆圈
for i in range(40):
draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
x = random.randint(0, width)
y = random.randint(0, height)
draw.arc((x, y, x + 4, y + 4), 0, 90, fill=rndColor())
# 画干扰线
for i in range(5):
x1 = random.randint(0, width)
y1 = random.randint(0, height)
x2 = random.randint(0, width)
y2 = random.randint(0, height)
draw.line((x1, y1, x2, y2), fill=rndColor())
img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
return img, ''.join(code)
if __name__ == '__main__':
img, code_str = check_code()
print(code_str)
with open('code.png', 'wb') as f:
img.save(f, format='png')
可视化图表
- highchart,国外。
- echarts,国内。
更多参考文档:https://echarts.apache.org/handbook/zh/get-started
文件上传
基本操作
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="text" name="username">
<input type="file" name="avatar">
<input type="submit" value="提交">
</form>
from django.shortcuts import render, HttpResponse
def upload_list(request):
if request.method == "GET":
return render(request, 'upload_list.html')
# # 'username': ['big666']
# print(request.POST) # 请求体中数据
# # {'avatar': [<InMemoryUploadedFile: 图片 1.png (image/png)>]}>
# print(request.FILES) # 请求发过来的文件 {}
file_object = request.FILES.get("avatar")
# print(file_object.name) # 文件名:WX20211117-222041@2x.png
f = open(file_object.name, mode='wb')
for chunk in file_object.chunks():
f.write(chunk)
f.close()
return HttpResponse("...")
案例:批量上传数据
<form method="post" enctype="multipart/form-data" action="/depart/multi/">
{% csrf_token %}
<div class="form-group">
<input type="file" name="exc">
</div>
<input type="submit" value="上传" class="btn btn-info btn-sm">
</form>
def depart_multi(request):
""" 批量删除(Excel文件)"""
from openpyxl import load_workbook
# 1.获取用户上传的文件对象
file_object = request.FILES.get("exc")
# 2.对象传递给openpyxl,由openpyxl读取文件的内容
wb = load_workbook(file_object)
sheet = wb.worksheets[0]
# 3.循环获取每一行数据
for row in sheet.iter_rows(min_row=2):
text = row[0].value
exists = models.Department.objects.filter(title=text).exists()
if not exists:
models.Department.objects.create(title=text)
return redirect('/depart/list/')
案例:混合数据(Form)
提交页面时:用户输入数据 + 文件(输入不能为空、报错)。
- Form生成HTML标签:type=file
- 表单的验证
- form.cleaned_data 获取 数据 + 文件对象 ```html {% extends ‘layout.html’ %}
{% block content %}
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"> {{ title }} </h3>
</div>
<div class="panel-body">
<form method="post" enctype="multipart/form-data" novalidate >
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label>{{ field.label }}</label>
{{ field }}
<span style="color: red;">{{ field.errors.0 }}</span>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">提 交</button>
</form>
</div>
</div>
</div>
{% endblock %}
```python
from django import forms
from app01.utils.bootstrap import BootStrapForm
class UpForm(BootStrapForm):
bootstrap_exclude_fields = ['img']
name = forms.CharField(label="姓名")
age = forms.IntegerField(label="年龄")
img = forms.FileField(label="头像")
def upload_form(request):
title = "Form上传"
if request.method == "GET":
form = UpForm()
return render(request, 'upload_form.html', {"form": form, "title": title})
form = UpForm(data=request.POST, files=request.FILES)
if form.is_valid():
# {'name': '武沛齐', 'age': 123, 'img': <InMemoryUploadedFile: 图片 1.png (image/png)>}
# 1.读取图片内容,写入到文件夹中并获取文件的路径。
image_object = form.cleaned_data.get("img")
# file_path = "app01/static/img/{}".format(image_object.name)
db_file_path = os.path.join("static", "img", image_object.name)
file_path = os.path.join("app01", db_file_path)
f = open(file_path, mode='wb')
for chunk in image_object.chunks():
f.write(chunk)
f.close()
# 2.将图片文件路径写入到数据库
models.Boss.objects.create(
name=form.cleaned_data['name'],
age=form.cleaned_data['age'],
img=db_file_path,
)
return HttpResponse("...")
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
在settings.py中进行配置:
import os
MEDIA_ROOT = os.path.join(BASE_DIR, “media”) MEDIA_URL = “/media/“
在浏览器上访问这个地址:<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)
<a name="34486692"></a>
### 案例:混合数据(form)
```python
from django import forms
from app01.utils.bootstrap import BootStrapForm
class UpForm(BootStrapForm):
bootstrap_exclude_fields = ['img']
name = forms.CharField(label="姓名")
age = forms.IntegerField(label="年龄")
img = forms.FileField(label="头像")
def upload_form(request):
title = "Form上传"
if request.method == "GET":
form = UpForm()
return render(request, 'upload_form.html', {"form": form, "title": title})
form = UpForm(data=request.POST, files=request.FILES)
if form.is_valid():
# {'name': '武沛齐', 'age': 123, 'img': <InMemoryUploadedFile: 图片 1.png (image/png)>}
# 1.读取图片内容,写入到文件夹中并获取文件的路径。
image_object = form.cleaned_data.get("img")
# media_path = os.path.join(settings.MEDIA_ROOT, image_object.name)
media_path = os.path.join("media", image_object.name)
f = open(media_path, mode='wb')
for chunk in image_object.chunks():
f.write(chunk)
f.close()
# 2.将图片文件路径写入到数据库
models.Boss.objects.create(
name=form.cleaned_data['name'],
age=form.cleaned_data['age'],
img=media_path,
)
return HttpResponse("...")
return render(request, 'upload_form.html', {"form": form, "title": title})
案例:混合数据(ModalForm)
models.py
class City(models.Model):
""" 城市 """
name = models.CharField(verbose_name="名称", max_length=32)
count = models.IntegerField(verbose_name="人口")
# 本质上数据库也是CharField,自动保存数据。
img = models.FileField(verbose_name="Logo", max_length=128, upload_to='city/')
定义ModelForm
from app01.utils.bootstrap import BootStrapModelForm
class UpModelForm(BootStrapModelForm):
bootstrap_exclude_fields = ['img']
class Meta:
model = models.City
fields = "__all__"
视图
def upload_modal_form(request):
""" 上传文件和数据(modelForm)"""
title = "ModelForm上传文件"
if request.method == "GET":
form = UpModelForm()
return render(request, 'upload_form.html', {"form": form, 'title': title})
form = UpModelForm(data=request.POST, files=request.FILES)
if form.is_valid():
# 对于文件:自动保存;
# 字段 + 上传路径写入到数据库
form.save()
return HttpResponse("成功")
return render(request, 'upload_form.html', {"form": form, 'title': title})
小结
- 自己手动去写
file_object = request.FILES.get("exc")
...
- Form组件(表单验证) ```python request.POST file_object = request.FILES.get(“exc”)
具体文件操作还是手动自己做。
- ModelForm(表单验证 + 自动保存数据库 + 自动保存文件)
- Media文件夹
- Models.py定义类文件要 img = models.FileField(verbose_name=”Logo”, max_length=128, upload_to=’city/‘) ```
知识点
中间件
在中间件的process_request方法
- 如果方法中没有返回值(返回None),继续向后走
- 如果有返回值 HttpResponse、render 、redirect,则不再继续向后执行。
定义中间件
```python from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse
class M1(MiddlewareMixin): “”” 中间件1 “””
def process_request(self, request):
# 如果方法中没有返回值(返回None),继续向后走
# 如果有返回值 HttpResponse、render 、redirect
print("M1.process_request")
return HttpResponse("无权访问")
def process_response(self, request, response):
print("M1.process_response")
return response
class M2(MiddlewareMixin): “”” 中间件2 “””
def process_request(self, request):
print("M2.process_request")
def process_response(self, request, response):
print("M2.process_response")
return response
<a name="wf333"></a>
#### 应用中间件 setings.py
```python
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'app01.middleware.auth.M1',
'app01.middleware.auth.M2',
]
登录(Cookie和Session)
登录成功后:
Cookie和Session,用户登录信息保存起来。
- cookie,随机字符串
- session,用户信息
在其他需要登录才能访问的页面中,都需要加入:
def index(request):
info = request.session.get("info")
if not info:
return redirect('/login/')
...
目标:在18个视图函数前面统一加入判断。
info = request.session.get("info")
if not info:
return redirect('/login/')
对 HttpResponse()对象的set_cookie方法进行设置 HttpResponse().set_cookie()
第一个参数是 键名 第二参数是对应的值
参数 max_age 设置过期时间,单位是秒
参数 expires 设置到那个时间过期 日期类型
# 编写视图函数,进行设置
from datetime import datetime,timedelta
def set_cookie(request):
"""设置cookie"""
response = HttpResponse("设置cookie")
''' max_age 设置过期时间,单位是秒 '''
# response.set_cookie('name', 'tong', max_age=14 * 24 * 3600)
''' expires 设置过期时间,是从现在的时间开始到那个时间结束 '''
response.set_cookie('name', 'tong', expires=datetime.now()+timedelta(days=14))
return response
获取cookie
利用request的request.COOKIES[‘键名’] 来获取cookie
# 视图函数中定义 get_cookie 方法
def get_cookie(request):
"""获取cookie"""
name = request.COOKIES['name']
return HttpResponse(name)
Session
使用重定向如果要传数据的话 可以用session来传输
request.session[‘key_name] = value
request.session['msg'] = u'用户未登录'
然后在模板中使用:
<h2>{{ request.session.username }}</h2> {# 输出username保存的值 #}
{# {{ 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。
# 跨request传递message,使用session。
self.request.session['create_app'] = name
return redirect(reverse_lazy('app:list', args=()))
2,在需要获取message的view中,加入消息。
# 获取创建组件成功的session提示,同request传递message。
create_app = self.request.session.pop('create_app', False)
if create_app:
messages.info(self.request, '{}创建成功,请编辑它的配置!'.format(create_app))
3,在前端网页中,显示此message。
{% for message in messages %}
<div class="alert alert-success alert-dismissible fade in" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<strong>组件创建提示!</strong> {{ message }}.
</div>
{% endfor %}
注销
def logout(request):
rep = redirect('/login/')
rep.delete_cookie("is_login")
return rep # 点击注销后执行,删除cookie,不再保存用户状态,并弹到登录页面
def logout(request):
""" 注销 """
request.session.clear()
return redirect('/login/')
Ajax请求
浏览器向网站发送请求时:URL 和 表单的形式提交。
- GET
- POST
特点:页面刷新。
除此之外,也可以基于Ajax向后台发送请求(偷偷的发送请求)。
- 依赖jQuery
- 编写ajax代码
$.ajax({
url:"发送的地址",
type:"get",
data:{
n1:123,
n2:456
},
success:function(res){
console.log(res);
}
})
GET请求
```python from django.shortcuts import render, HttpResponse$.ajax({
url: '/task/ajax/',
type: "get",
data: {
n1: 123,
n2: 456
},
success: function (res) {
console.log(res);
}
})
def task_ajax(request): print(request.GET) return HttpResponse(“成功了”)
<a name="IuRHA"></a>
#### POST请求
```css
<form action='{% url 'LOGIN' %}' method="post">
{% csrf_token %} {# 增加验证,是否是通过get请求先访问页面,然后再进行的提交,否则无法直接提交 #}
用户名<input type="text" name="username">
密码<input type="password" name="pwd">
<br>
<input type="submit" value="登录">
</form>
$.ajax({
url: '/task/ajax/',
type: "get",
data: {
n1: 123,
n2: 456
},
success: function (res) {
console.log(res);
}
})
from django.shortcuts import render, HttpResponse
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def task_ajax(request):
print(request.GET)
print(request.POST)
return HttpResponse("成功了")
关闭绑定事件
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<h1>任务管理</h1>
<h3>示例1</h3>
<input id="btn1" type="button" class="btn btn-primary" value="点击"/>
</div>
{% endblock %}
{% block js %}
<script type="text/javascript">
$(function () {
// 页面框架加载完成之后代码自动执行
bindBtn1Event();
})
function bindBtn1Event() {
$("#btn1").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: {
n1: 123,
n2: 456
},
success: function (res) {
console.log(res);
}
})
})
}
</script>
{% endblock %}
ajax请求的返回值
一般都会返回JSON格式。
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<h1>任务管理</h1>
<h3>示例1</h3>
<input id="btn1" type="button" class="btn btn-primary" value="点击"/>
</div>
{% endblock %}
{% block js %}
<script type="text/javascript">
$(function () {
// 页面框架加载完成之后代码自动执行
bindBtn1Event();
})
function bindBtn1Event() {
$("#btn1").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: {
n1: 123,
n2: 456
},
dataType: "JSON",
success: function (res) {
console.log(res);
console.log(res.status);
console.log(res.data);
}
})
})
}
</script>
{% endblock %}
import json
from django.shortcuts import render, HttpResponse
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
def task_list(request):
""" 任务列表 """
return render(request, "task_list.html")
@csrf_exempt
def task_ajax(request):
print(request.GET)
print(request.POST)
data_dict = {"status": True, 'data': [11, 22, 33, 44]}
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
- 常见第三方模块:
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()
<a name="1349b522"></a>
### 前端开发
<a name="jrrYi"></a>
#### HTML
- 块级和行内标签(div、span) 块级:div/h系列 行内:span/a (设置高度、宽度、边距无效)
Form表单
关于a标签 百度 超链接去跳转。 做锚点
<a href="#m1">第一章</a>
<a href="#m2">第二章</a>
<div id="m1" style="height: 1000px;">第一章 谢新雪</div>
<div id="m2" style="height: 1000px;">第二章 单独的</div>
```
CSS
- 位置
- 标签 <div style="xxx">
- style代码块
<style>
div { }
#v1 { }
.v2 {}
</style>
- 文件中
- 选择器
div { }
#v1 { }
.v2 { }
div[xx='11'] { }
- 样式
color;fonts-ize; background-color; padding; margin;
float:left; ,脱离文档流。 clear:both; :after
JavaScript & jQuery
- 本质上:找到标签;操作标签。
- 找标签
$("#x1")
$(".x1")
$("div")
$("input[type='text']") 找到 input 标签且 type='text'
- 操作标签
$("#x1").text() <div id='x1'>dd</div>
$("#x1").text("xxx") <div id='x1'>xxx</div>
$("#x1").val() <input id='x1' />
$("#x1").val("xxx") <input id='x1' />
$("#x1").attr("uu") <div id='x1' uu="123">dd</div>
$("#x1").attr("uu","999") <div id='x1' uu="999">dd</div>
$("#x1").empty() <div id='x1'>dd</div> - 清空内容
$("#x1").remove() <div id='x1'>dd</div> - 整个标签删除
BootStrap
- 支持响应式布局,根据屏幕的宽度调整布局。
- 栅格,12份。
- 常见的样式:
- container / container-fluid
- 面板
- 按钮
- 表单
- 表格
- 对话框
第三方插件
- 插件一般都包含:CSS、JavaScript,开发使用时候
- 引入css、js(依赖jQuery)
- 使用
关于注释
- Python语言
# 注释
""" 注释 """
- HTML
<!-- -->
- CSS注释
/* 注释 */
- JavaScript
// 注释
/* 注释 */
总结
F和Q
更多
关于django的开发知识点,更多的案例:
- Python基础(课件 https://gitee.com/wupeiqi/python_course)
https://www.bilibili.com/video/BV1m54y1r7zE
- 并发编程(进程线程协程) ``` https://www.bilibili.com/video/BV1Ev411G7i3?spm_id_from=333.999.0.0
不建议小白学(协程)
https://www.bilibili.com/video/BV1NA411g7yf?spm_id_from=333.999.0.0
- MySQL数据库
```python
# 2021最新推荐
https://www.bilibili.com/video/BV15R4y1b7y9?spm_id_from=333.999.0.0
# 2017年
https://www.bilibili.com/video/BV1DE411n7fU?
- 前端开发
https://www.bilibili.com/video/BV1QE411j7bV?spm_id_from=333.999.0.0
- django开发知识点
https://www.bilibili.com/video/BV1zE411x7LG
https://www.bilibili.com/video/BV1JE411V7xk
- 项目开发
任务管理平台:https://www.bilibili.com/video/BV1uA411b77M
- 进阶项目(增删改查、权限)
https://space.bilibili.com/283478842/channel/detail?cid=91596&ctype=0
- 前后端分离的项目: django + drf框架 + vue.js ```
- Django
- drf框架
- git 版本控制和协同开发 + 任务管理平台
https://www.bilibili.com/video/BV19E411f76x?spm_id_from=333.999.0.0
- 微信小程序 + Django + drf框架编写
https://www.bilibili.com/video/BV1jC4y1s7QD?spm_id_from=333.999.0.0