django 武沛齐老师-最后一篇随笔
基础
https://www.cnblogs.com/wupeiqi/articles/5237704.html
进阶
https://www.cnblogs.com/wupeiqi/articles/5246483.html
2021-02-02补充内容
以前整理的Django基础带笔记(更加全面)
https://www.cnblogs.com/hany-postq473111315/p/13377190.html
安装
pip install django==1.11.14 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
卸载
pip uninstall django
创建 django 项目
django-admin startproject 项目名
django-admin startproject victory
运行 django 项目
cd victory
python manage.py runserver
创建 app
python manage.py startapp app名称
python manage.py startapp app01
urls 文件
urlpatterns = [ ] 对应 url 映射的列表
urlpatterns = [
url(r'^网址名称/', 包模块.函数名),
url(r'^网址名称/', 函数名),
]
wsgi 一套规则,接口,创建 socket
产品上线不使用默认的 wsgi , 使用 uwsgi + nginx
manage.py 管理 django 程序
settings 配置文件
app 注册
app 名称.apps.app 名称Config 或 app 名称
app01.apps.App01Config 或 app01
templates 模板注册
'DIRS': [os.path.join(BASE_DIR, 'templates')],
配置静态文件夹 static
创建 static 静态文件夹
STATICFILES_DIRS = (
os.path.join(BASE_DIR,'static'),
)
设置中文
LANGUAGE_CODE = 'zh-hans'
设置时区
TIME_ZONE = 'Asia/Shanghai'
设置数据库为 mysql (注:先安装 mysqlclient, pip install mysqlclient)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '数据库名称',
'USER':'用户名',
'PASSWORD':'密码',
'HOST':'127.0.0.1',
'PORT':'3306'
}
}
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'app02',
'USER':'root',
'PASSWORD':'root',
'HOST':'127.0.0.1',
'PORT':'3306'
}
}
ORM 对象关系映射,创建数据库表不需要使用select , insert 语句了
数据库迁移
python manage.py makemigrations
python manage.py migrate
app 目录
migrations 记录做过哪些修改数据表结构的操作
__init__ 文件,python3 可以删除,python2 不可以删除
python2 默认 不带 __init__ 文件为普通文件夹,导入会报错
admin 后台管理
在 admin 中,导入 app 的 models 文件
from app01 import models
将 models 里面的数据表进行注册
admin.site.register(models.UserInfo)
admin.site.register(models.UserType)
两张表内容如下
class UserType(models.Model):
name = models.CharField(max_length=32)
class UserInfo(models.Model):
username = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
email = models.CharField(max_length=32)
user_type = models.ForeignKey('UserType')
# 使用 '' 将类名包裹,进行创建外键
创建超级用户
python manage.py createsuperuser
示例:
用户名 hany
密码 hany12345.
超级用户登录后,可以对数据表增加数据等操作
apps 配置当前 app
models ORM 操作,通过命令创建数据库表结构
tests 单元测试
views 业务逻辑文件,写函数
伪装数据库
项目的 __init__ 文件下
import pymysql
pymysql.install_as_MySQLdb()
生命周期
用户发送请求到路由系统,如果匹配成功,执行相对应的 views 中的函数
到数据库中取出数据,在模板 html 上进行页面渲染数据 返回到用户的浏览器上
urls 操作
url(r'^路由映射/', views.函数名),
url(r'^register/', views.register),
url(r'^路由映射-(?P<形参名>\d+).html', views.函数名),
url(r'^detail-(?P<cid>\d+).html', views.detail),
url(r'路由映射',include("app名称.urls"))
url(r'app02',include("app02.urls"))
注:include 内参数加引号,urls 需要自己创建
在用户创建的 urls 中,继续进行地址映射,写在 urlpatterns = [ ]中
app 不要忘记在 settings 中进行注册
models 操作
创建数据表时,继承 models.Model
示例
class UserInfo(models.Model)
创建字符串类型数据 models.CharField
示例
username = models.CharField(max_length=32)
id 主键会自动创建,并递增
使用 AutoField,并且声明主键 primary_key=True 可以不让系统创建 id 列
示例
uid = models.AutoField(primary_key=True)
字段参数
null 字段是否为空
default 默认值
示例
code = models.CharField(max_length=32,null=True,default="SA")
primary_key 主键
db_column 列名
db_index 索引 , unique 唯一索引
unique_for_date 对日期做索引,unique_for_month 对月做索引, unique_for_year 对年做索引
auto_now=True 创建时生成时间
示例
ctime = models.DateField(auto_now=True,null=True)
auto_now_add=True 修改时自动更新时间
choice 选项
示例 , choices 为 一个嵌套的元组对象
user_type_choices = (
(1,'super man'),
(2,'common man'),
(3,'man'),
)
user_type_id = models.IntegerField(choices=user_type_choices,default=2)
verbose_name 备注字段
editable 字段是否可以被编辑
help_text 字段输入提示
validators 自定义错误信息
to_field 与哪一列进行关联
创建整数类型数据 models.IntegerField
示例
user_type_id = models.IntegerField(choices=user_type_choices,default=2)
外键关联 models.ForeignKey
示例 第一个参数为类名,uid 为关联的字段
usergroup = models.ForeignKey('UserGroup',to_field='uid')
会自动生成 usergroup_id 列,usergroup 为对象,可以使用 usergroup.uid 进行获取外联表的数据
创建 ip
示例 , protocol默认为 'both'
ip = models.GenericIPAddressField(protocol="ipv4",db_index=True)
多对多 , 不能加额外字段列
models.ManyToManyField('类名')
一对多,多对多示例
class Business(models.Model):
caption = models.CharField(max_length=32)
code = models.CharField(max_length=32,null=True,default="SA")
class Host(models.Model):
nid = models.AutoField(primary_key=True)
hostname = models.CharField(max_length=32,db_index=True)
ip = models.GenericIPAddressField(protocol="ipv4",db_index=True)
port = models.IntegerField()
b = models.ForeignKey(to="Business", to_field='id')
class Application(models.Model):
name = models.CharField(max_length=32)
r = models.ManyToManyField("Host")
注:会自动创建一个新的表,内部为其他表的 id 主键
obj = Application.objects.get(id=1)
增加数据
obj.r.add(1)
obj.r.add(1,2,3)
obj.r.add(*[1,2,3])
删除数据
obj.r.remove(2,4,5)
obj.r.clear()
更新数据
obj.r.set([3,5,7])
多对多 , 自定义创建第三张表 , 可以自己定义第三张表的字段
示例
class HostApp(models.Model):
hobj = models.ForeignKey(to='Host',to_field='nid')
aobj = models.ForeignKey(to='Application',to_field='id')
status = models.CharField(max_length=32)
增加数据
HostApp.objects.create(hobj_id='xxx',aobj='xxx',status='xxx')
html 操作
导入 jquery
<script src="/static/jquery.min.js"></script>
导入静态文件
<link rel="stylesheet" href="/static/commons.css">
使用 {{ 变量名 }} 进行显示变量
<span style="color: red;">{{ error_msg }}</span>
for 循环
{% for 对象 in 传递过来字典的键 %}
<ul>
<li> {{ 对象 }} </li>
</ul>
{% endfor %}
遍历字典中的键
{% for num in user_num.keys %}
<ul>
<li> {{ num }} </li>
</ul>
{% endfor %}
遍历字典中的值
{% for num in user_num.values %}
<ul>
<li> {{ num }} </li>
</ul>
{% endfor %}
遍历字典的所有元素
{% for key,value in user_num.items %}
<ul>
<li> {{ key }} - {{ value }}</li>
</ul>
{% endfor %}
遍历列表
{% for name in user_list %}
<ul>
<li> {{ name }} </li>
</ul>
{% endfor %}
取索引对象
第一个元素
对象.0 {{ user_list.0 }}
对应索引元素名
对象.元素名 {{ user_num.zero }}
if 语句
{% if 条件%}
语句
{% else %}
语句
{% endif %}
{% if 条件 %}
语句
{% elif 条件 %}
语句
{% else %}
语句
{% endif %}
跳转链接 href
<a href="app名称/路由">内容</a>
示例 , 跳转到 app02 下的 student 中
<a class="menu" href="/app02/student">学生管理</a>
循环计数 forloop
从 1 开始
{{ forloop.counter }}
从 0 开始
{{ forloop.counter0 }}
是否是第一个 , 返回 True 或 False
{{ forloop.first }}
是否是最后一个 , 返回 True 或 False
{{ forloop.last }}
倒序到 1 为止
{{ forloop.revcounter }}
倒序到 0 为止
{{ forloop.revcounter0 }}
上一层循环
{{ forloop.parentloop }}
ajax
$.ajax({
url:"路由地址",
type:"GET 或 POST 请求方式",
data:数据, data: $('#select 标签的 id 值').serialize(), 获取序列化数据
dataType:'数据类型'
success: function(data){
对获取到的数据 data 要进行的操作
JSON.parse(data) 对返回的字符串转换为对象
location.reload(), 刷新
location.href = '某个地址' , 跳转
}
}
views 操作
形参可以使用 request , *args , **kwargs
request.method 提交方式
GET , POST 以及其他方式
request.environ 获取所有的请求信息
获取 cookies
request.COOKIES
获取用户输入的值
request.POST['html 中的name 属性的值']
request.POST.get('html 中的name 属性的值',None)
password = request.POST.get('password',None)
request.POST.getlist('html 中的name 属性的值')
request.POST.getlist('favor')
返回页面上显示的字符串
return HttpResponse('<标签名>字符串</标签名>')
return HttpResponse('<h2>Hello</h2>')
页面跳转
return redirect('网址')
return redirect('/home/')
注: home 前面的 / 为 ip : 端口号/
页面渲染
return render(request,'html文件名.html'[,变量])
return render(request,'login.html')
return render(request,'login.html',{'error_msg':error_msg})
注: 字典的键为在 html 中使用的变量名称
数据库增删改查
字段值大于 1 的
models.类名.objects.filter(字段__gt=1)
字段值大于等于 1 的
models.类名.objects.filter(字段__gte=1)
字段值等于 1 的
models.类名.objects.filter(字段=1)
字段值小于 1 的
models.类名.objects.filter(字段__lt=1)
字段值小于等于 1 的
models.类名.objects.filter(字段__lte=1)
获取指定字段的值
models.类名.objects.all().values('字段1','字段2')
注:返回的是 QuerySet 类型,内部为字典对象
models.类名.objects.all().values_list('字段1','字段2')
注:返回的是 QuerySet 类型,内部为元组对象
示例
models.UserInfo.objects.all().values('username', 'password')
获取文件
注: 在文件上传时,在 form 表单中加入 enctype="multipart/form-data" 表示上传的是文件
上传的文件到 request.FILES 中进行查找
file = request.FILES.get('html 中的name 属性的值')
file.chunks() 一个可迭代对象,包含有上传的文件
file.name 文件名
file.size 文件大小
获取上传文件示例(fff 为 name 的值,upload为在项目根路径下创建的文件夹):
file = request.FILES.get('fff')
import os
file_location = os.path.join('upload',file.name)
f = open(file_location,mode = 'wb')
for i in file.chunks():
f.write(i)
f.close()
根据用户点击的不同,生成不同的详细信息
示例:
views 中:
user_info = {
'1':['xiaoming','nv','21'],
'2':['xiaolang','nan','22'],
'3':['xiaomi','nv','23'],
'4':['xiaole','nan','24'],
}
def index(request):
return render(request,'index.html',{'user_info':user_info})
def detail(request,cid):
detail_info = user_info[cid]
return render(request,'detail.html',{'detail_info':detail_info})
urls 中
url(r'^detail-(?P<cid>\d+).html',views.detail),
在括号中写入 ?P<cid> 表示传递给形参 cid
html
index 中
{% for user_key in user_info.keys %}
<a href="/detail-{{ user_key }}.html">{{ user_key }}</a><br/>
{% endfor %}
detail 中
<h2>详细信息</h2>
<div style="margin: auto;color: burlywood">
用户名:{{ detail_info.0 }}<br/>
性别:{{ detail_info.1 }}<br/>
年龄:{{ detail_info.2 }}<br/>
</div>
获取当前 url
request.path_info
增加数据
第一种
models.类名.objects.create(
字段1=值1,
字段2=值2,
...
)
示例
models.UserInfo.objects.create(
username='www',
password='111'
)
第二种
obj = models.类名(字段1=值1,字段2=值2)
obj.save()
示例
obj = models.UserInfo(username='two',password='...')
obj.save()
查询数据
查询全部数据
models.类名.objects.all()
示例 username 为字段名
all = models.UserInfo.objects.all()
for user in all:
print(user.username,user.password)
查询指定某一行数据
models.类名.objects.filter(字段1=值1[,字段2=值2])
示例,对查询到数据可以进行循环输出数据
result = models.UserInfo.objects.filter(username='hany')
for user in result:
print(user.username,user.password)
示例 , 获取外键所在表的数据 , 外键名为 b 通过.进行获取数据,b_id 为在表中的字段
v1 = models.Host.objects.filter(nid=1).first()
print(v1.nid,v1.hostname,v1.ip,v1.port,v1.b_id)
print(v1.b.id,v1.b.caption)
注:如果报错,可以考虑使用 __ 进行查询 b__caption
v2 = models.Host.objects.filter(nid=1)
print(v2.values('b__caption'))
删除数据
删除全部数据
models.类名.objects.all().delete()
示例
models.UserInfo.objects.all().delete()
删除一条数据
models.类名.objects.filter(条件).delete()
示例
models.UserInfo.objects.filter(username='www').delete()
更新数据
更新全部数据
models.类名.objects.all().update(字段=值)
示例
models.UserInfo.objects.all().update(password='666')
更新一条数据
models.类名.objects.filter(条件).update(字段=值)
示例
models.UserInfo.objects.filter(id=1).update(password='111')
filter 后可以跟
count() 获取数据个数
示例 , 当不存在对应数据时,obj_count 为 0
obj_count = models.UserInfo.objects.filter(username=username,password=password).count()
print(obj_count)
first() 获取第一条数据
示例 , 使用了 first 之后,可以使用对象直接输出字段值
obj = models.UserInfo.objects.filter(username=username,password=password).first()
print(obj.username)
登录示例 , 没有获取到数据为 None
if not obj:
error_msg = 'name or password is error '
return render(request,'登录.html',{'error_msg':error_msg})
else:
return render(request, '主页.html')
问题
SyntaxError: Generator expression must be parenthesized (widgets.py, line 152) 问题
去掉最后面的 , 号
跨站请求伪造 Forbidden (403) CSRF verification failed. Request aborted.
找到 settings 中的 MIDDLEWARE 将 csrf 注释掉
You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set.
模板中提交的 action 数据要和 urls 的 urlpatterns 的 网址名称一样,要么都带 / , 要么都不带 /
2021-02-02补充内容:
{% extends 'base.html' %}
{#继承 base.html #}
{% load static %}
{# 用在开始,导入 static静态文件 #}
{% block header %}
<h2> 填写 block 块的 header 内容</h2>
{% endblock %}
2020-08-17
本文来自博客园,作者:Hany47315,转载请注明原文链接:https://www.cnblogs.com/hany-postq473111315/p/13515923.html