django
django:
django-admin startproject myweb
目录结构
myweb
- myweb
- init //python2必须要有,没有别人没法导入
- settings //配置文件
- url //url对应关系
- wsgi //遵循wsgi规范,wsgi是规则是接口,创建socket用的
- manage.py //管理django程序:
python3 manage.py runserver 127.0.0.01:8001
python3 manage.py startapp xx
python3 manage.py makemigrattions
python3 manage.py migrate
app:
共同使用一个配置文件
python3 manage.py startapp app_name
app目录都有什么
- apps //对当前app最配置管理
- admin //django默认管理程序
- migrations //数据库修改表结构
- models //创建数据库表
- tests //单元测试
- views //业务逻辑
settings:
//配置模板路径
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')] , //模板路径
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
'/var/www/static/',
]
//CSRF报警
django.middleware.csrf.CsrfViewMiddleware'
//获取用户提交方法
request.method
//获取自定义的name,没有name是none
request.body //POST,GET都是利用这个http的body
user = request.POST.get('user', None) //操作文件的话默认只能拿到文件名
user = request.GET.get('user', None)
user = request.FILES.get('user', None)
user = request.POST.getList('user', None) //获取checkbox等多选
request.Meta //获取http请求头的
request.method(POST,GET,PUT)
request.path_info
request.COOKIES
<form enctype="multipart/form-data">
file = request.FILES.get('file_name')
print(file_name, type(file_name), file_name.name)
file_path = os.path.join('upload', file_name.name)
for i in obj.chunks():
f.write(i)
f.close()
基础用法
//前端接收后端的值
前端
<span style="color:red">{{ error_msg }}</span>
后端
return render(request, 'login.html', {'error_msg': error_msg})
//跳转超链接
from django.shortcuts import redirect
return redirect('http://www.baidu.com') //只能填url
//返回字符串:
return HttpResponse("dasdsadsad") //接收字符串,字节
//模板语言的for循环
list action:
list_1 = [
{'username': '123'}
{'gender': 1}
{'email': "dwa@qwe.com"}
]
{% for item in list_1 %}
<tr>
<td>{{ row.username }}</td>
<td>{{ row.gender.key1s }}</td>
<td>{{ row.email }}</td>
<td>{{ forloop.counter }}</td> //计数器, 从1开始
<td>{{ forloop.counter0 }}</td> //计数器, 从0开始
<td>{{ forloop.revcounter }}</td> //计数器, 倒序
<td>{{ forloop.last }}</td> //是否是最后一个
<td>{{ forloop.first }}</td> //是否是第一个
</tr>
{% endfor %}
dict action:
dict_1 = {
'k1': 'v1',
'k2': 'v2',
'k3': 'v3',
'k4': 'v4'
}
{% for k in dict_1.keys %} //print keys
{% for v in dict_1.values %} //print values
{% for k, v in dict_1.items %} //print keys, values
<tr>
<td>{{ k }}</td>
<td>{{ v }}</td>
<td>{{ k }} ---> {{ v }}</td>
</tr>
{% endfor %}
{% if condition%}
segment
{% else %}
segment
{% endif %}
路由系统:
FBV:
function base view
url里对应的是一个函数
CBV
class base view
也可以对应一个class
path(r'haha/', login_views.Home.as_view()), //as_view()固定用法
函数能根据方法类型响应方法,如get,post,head,put,patch,delete,options.trace
from django.views import View //必须继承自view类
class Home(View):
def get(self, request):
print(request.method)
return render(request, 'home.html')
def post(self, request):
print(request.method)
return render(request, 'home.html')
正则匹配:
直接在url里传值了, 不是get和post, 这样SEO优化看来是静态页面
http://0.0.0.0:22222/detail-3.html
urls:
from django.urls import re_path
re_path(r'^detail-(\d+).html', login_views.detail),
re_path(r'^detail-(?P<username>\d+)-(?P<password>\d+).html', login_views.detail),
app.views:
def detail(request, nid):
def detail(request, *args, **kwargs):
return HttpResponse(nid)
name:
对URL路有关系命名, 更简便的生成一个URL
urls
path(r'haha/', login_views.Home.as_view(), name='home11')
模板语言
{% url "home11" 1 2 3 %} //参数以空格隔开
reverse:
//根据name生成一个url
from django.urls import reverse
v = reverse('home11', args=(33,22,))
v = reverse('home11', kwargs=('username': 33,'password': 22,))
URL分类 :
from django.conf.urls import url.include
urlpatterns = [
path(r'cmdb', include('cmdb.urls')),
]
//在名字为cmdb的app里创建一个py文件叫做urls,然后正常写入规则
默认值
命名空间
ORM:
Object relation Map
DB first: 先创建表,再生成类
pass
Code first: 先创建类,再生成表
1.根据类自动创建数据库表
2.根据类对数据库表中的数据进行各种操作
注册app:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'login', //在settings里添加上这个app, 不然无法使用 makemigrations
]
from django.db import models
// Create your models here.
model文件中的表(类)定义
class UserInfo(models.Model):
// auto create id column auto increment
// create user column & figer length
username = models.CharField(max_length=32) // 字符长度
// create passwd column & figer length
password = models.CharField(max_length=64)
// value can be true
gender = models.CharField(max_length=10, null=True)
python3 manage.py makemigrations //生成数据库临时文件
python3 manage.py migrate //生成数据库内容, 默认情况下是SQLite, 表名是AppName_TableName
django默认使用mysqldb
mysqldb解决办法
MySQL:
配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', // 驱动(ENGINE)
'HOST': '192.168.20.61', // 主机地址(HOST)
'PORT': '3306', // 端口号(PORT)
'NAME': 'hinimix', // 数据库(NAME)
'USER': 'hinimix', // 用户名(NAME)
'PASSWORD': 'hinimix', // 登录密码(PASSWORD)
}
}
执行
sudo apt install python-dev
sudo apt-get install libmysqlclient-dev
sudo pip3 install mysqlclient
python3 manage.py makemigrations
python3 manage.py migrate
pymysql解决办法
在app目录里
import pymysql
pymysql.install_as_MySQLdb()
CRUD操作:
Create:
from login import models
1
models.UserInfo.objects.create(
username='root',
password='123'
)
2
obj = models.UserInfo(username='sb', password='234')
obj.save()
3
dict = {'username': 'hnm', 'password': '21'}
obj = models.UserInfo(**dict)
obj.save()
Retrieve
result = models.UserInfo.objects.all() // QuerySet,内部元素是对象, result QuerySet类型 ==>LIST
result = models.UserInfo.objects.all().values('comuln1', 'column2') // QuerySet,内部元素是字典, result QuerySet类型 ==>LIST
result = models.UserInfo.objects.all().values_list('id', 'caption') // QuerySet,内部元素是元组,
// result QuerySet类型 ==>LIST
result2 = models.UserInfo.objects.filter(username='hnm', password='21') //组合城and条件
result2 = models.UserInfo.objects.filter(username='hnm', age__gt='21') //组合城and条件,age大于21
dic = {'username': 'hnm', 'password':'21'}
result2 = models.UserInfo.objects.filter(**dic) //组合城and条件,可以用字典
result2 = models.UserInfo.objects.filter(username='hnm', password='21').first() //直接是一个对象
result2 = models.UserInfo.objects.filter(username='hnm', password='21').count() //个数
Update
result = models.UserInfo.objects.all().update(password='666)
result2 = models.UserInfo.objects.filter(username='hnm', password='21').update(password='666') //值为1或0
Delete
result = models.UserInfo.objects.all().delete() // result QuerySet类型 ==>LIST
result2 = models.UserInfo.objects.filter(username='hnm', password='21').delete()
print(result.query) // 查看执行过程
Django admin
Django ORM字段类型
test0 = models.CharField(max_length=64)
test1 = models.EmailField(max_length=30, null=True)
test2 = models.URLField(max_length=100)
test3 = models.GenericIPAddressField(max_length=20) // IPv4 | IPv6
test4 = models.AutoField(primary_key=True) // auto increment
把表注册到admin
// 在admin文件里添加以下内容, 能通过django admin来管理login的数据库
from login import models
// Register your models here.
admin.site.register(models.UserInfo)
python3 manage.py createsuperuser
Django会自动检查test字段里的字符串是否符合Email格式
参数:
null //允许为空
default //默认值
primary_key //主键
db_column //列名
db_index //索引
unique //唯一索引
unique_for_date //对日唯一索引
unique_for_month //对月唯一索引
unique_for_year //对年唯一索引
auto_now //创建时自动生成
auto_now_add //更新时自动更新
test5 = models.DateField(auto_now_add=True, null=True)
test6 = models.DateField(auto_now=True, null=True)
result = models.TestInfo.objects.create(test7='aa')
result.save()
choices //在django admin里提示选项
user_type_choice = (
(1, 'super user'),
(2, 'midle user'),
(3, 'lower user')
)
user_type_id = models.IntegerField(choices=user_type_choice, default=1)
blank = True: //在django admin中可以为空
verbose_name: //在django admin中显示的中文字符
editable: //在django admin中是否能被编辑
error_message //在django admin中错误信息
help_text //在django admin中提示
validators //在django admin中自定义验证机制
外键:
class UserType(model.Model):
caption = models.CharField(max_length=32)
class User(models.Model):
age = models.IntergerField()
name = models.CharField(max_length=10)
user_type = models.ForeignKey("UserType", to_field='id') // 约束
跨表:
写在objects后面, 都是用__跨表
其他时候,用.跨表
AJAX
不用像form一样提交之后刷新页面
依赖JQuery
最简单的固定格式
$.ajax({
url: '/host', //目标地址
type: "POST", //提交方法
data: {'k1':123, 'k2':456}, //提交的值
data: $(//form_name)/serialize(), //获取form的值一起获取,发给后台
success: function(data){ //匿名回调函数
}
})
$.get
$.post
$.getJson
建议,永远让服务器端返回一个字典, ajax通过status判断取error还是data
dict = {'status': True, 'error': None, 'data':None}
return HttpResponse(json.dumps(dict))
前端获取字符串转化为对象
JSON.stringify(obj) //对象转换为字符串
JSON.parse(str) //字符串转化为对象
var obj = JSON.parse(data) //将后端来的值变成了
$('//error_box').text(obj.error())
后端代码
def test_ajax(request):
a = request.GET.get('user')
b = request.GET.get('password')
print(a, b)
return HttpResponse(a, b)
多对多:
自定义关系:
class Host(models.Model):
nid = models.AutoField(primary_key=True)
hostname = models.CharField(max_length=32, db_index=True)
class Application(models.Model):
name = model.CharField(max_length=10)
class HostToApp(models.Model):
hobj = models.ForeignKey(to='Host', to_field='nid')
aobj = models.ForeignKey(to='Application', to_field='id')
自动创建关系表:
class xxx(models.Model):
r = models.ManyToManyField("Other_table_name")
obj = xxx.objects.get(id=1)
obj.r.add(1)
obj.r.add(2, 3, 4)
obj.r.add(*[1,2,3,4]) //增加多个关系
obj.r.remove(1)
obj.r.remove(2, 3, 4)
obj.r.remove(*[1,2,3]) //删除多个关系
obj.r.clear() //清除xxx id=1的
obj.r.set([3, 5, 7])
模板:
继承:
{% extends 'muban.html' %} //继承muban.html
{% block css %}{% endblock %} //方便写自己的css
{% block muban_name %} //定义模板中的block
<a> aaaaa aa </a>
{% endblock %} //在html中补足内容
{% block js %}{% endblock %} //方便写自己的js
导入:
{% include "tag.html" %} //在当前位置导入tag.html
simple tag帮助方法:
{{ item.event_start|date:"Y-m-d H:i:s" }} //item接收后台的字符串,按指定类型输出
{{ bio|truncatewords: "30" }} //bio:后台传过来的字符串, 只保留前30
{{ my_list|first|upper }} //my_list首字母大写
{{ name|lower }} //name全小写
自定义simple tag(前端使用后端的函数):
1.在app下创建templatetags文件夹
2.创建任意py文件
3.引入django.utils.safestring中的mark_safe
4.创建一个template对象register,不能改名
5.定义函数加上装饰器
6.settings文件中注册app
7.在静态顶部{% load 文件名 %}
8.在静态下面引用函数名 {% function_name %}
settings:
INSTALLED_APPS= {
app_name,
}
后端:
app下templatetags
写入xxoo.py
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
@register.simple_tag
def hinimix(argv1, argv2):
return 123
前端:
{% load xxoo.py %}
{% hinimix argv1 argv2 %} //有空格没关系
缺点:
不能作为if条件
优点:
参数任意
filter:
register = template.Library()
@register.filter
{{ "aaa"|hinimix:"argv1,argv2" }}
缺点:
参数最多2个,不能加空格
{{ "参数1"|函数名:"参数2,参数3" }}
优点:
能作为if条件
自定义分页:
xss:
前端:
{{ page_str|safe }}
后端:
mark_safe(page_str)
装饰器认证登录:
FBV:
def auth(func):
def inner(request, *args, **kwargs):
v = request.COOKIES.get('username')
if not v:
return redirect('/login/')
return func(request, *args, **kwargs)
CBV:
from django.utils.decorators import method_decorator
在class里添加
@method_decorator(auth)
def dispatch(self, request, *args, **kwargs)
return super(Order, self).dispatch(request, (args, **kwargs)
或
@method_decorator(auth, name='dispatch')
class Order(views.View):
pass
cookie:
存放在浏览器上的一个文件, 关闭浏览器失效
result = redirect('/index/')
res.set_cookie('username', u, max_age=100) //max_age cookie过期时间,单位s
current_date = datetime.datetime.utcnow() + datetime.timedelta(seconds=5)
res.set_cookie('username', u, expires=currend_date) //expires cookie过期时间 datetime类型
return res
response=HttpResponse(a)
response.set_cookie('key', "value", expires[current_date)
response['name'] = 'hinimix' //自定义响应头
return response
obj = HttpResponse('s')
obj.set_signed_cooke("key_name", "value_name", salt="asdsad") //加密cookie
request.get_signed_cooke("key_name", salt="asdsad") //解密cookie
其他参数:
path= "/" //生效路径, /表示默认所有url里都生效
domain=None //生效域名,当前域名或子域名
secure=false //true:支持https
httponly=True //只支持http传输, 不会通过js获取到
v = request.COOKIES.get('username')
session:
敏感信息不适合放在cookie中,适合放在session中
是保存在服务器端的键值对, 依赖于cookie
// 所有键, 值, 键值对
request.session.keys()
request.session.iterkeys()
request.session.values()
request.session.itervalues()
request.session.items()
request.session.iteritems()
//用户session的随机字符串
request.session.session_key
//将所有session失效日期小于当前日期的数据删除
request.session.clear_expired()
//检查用户session的随机字符串,在数据库中是否存在
request.session.exists("session_key")
//删除当前用户的所有session数据
request.session.delete("session_key")
常用的:
request.session['k1'] = 123
request.session.setdefault('k1', 123) #存在则不设置
del request.session['k1']
request.session.set_expiry(value)
//如果value是证书,session会在这些秒之后失效
//如果value是datetime或者timedelta, session就会在这个时间后失效
//如果value是0, 用户关闭浏览器session就会失效
//如果value是None, session会依赖全局session失效策略.
//默认是2周
Django Session通用配置
SESSION_COOKIE_NAME = "sessionid" //sessin的cookie保存在浏览器上时候key的名字
SESSION_COOKIE_PATH = "/" //session的cookie保存的路径
SESSION_COOKIE_DOMAIN = None //session的cookie保存的域名
SESSION_COOKIE_SECURE = False //是否https传输cookie(默认)
SESSION_COOKIE_HTTPONLY = True //是否session的cookie只支持http传输
SESSION_COOKIE_AGE= 1209600 //session的cookie失效日期(2周)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False //是否关闭浏览器时候让session过期
SESSION_SAVE_EVERY_REQUEST = False //是否每次请求都保存session
//用缓存存储session,引擎配置
#SESSION_ENGINE = 'django.contrib.sessions.backends.cache' //引擎
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'default'
SESSION_SAVE_EVERY_REQUEST = True