web应用程序

server端建立socket,不断地accept,当收到客户端连接信号之后,服务端向客户端发送数据,将html网页打开,read出来,并发送至客户端,这样客户端就可以浏览到网页的内容

http协议:

包头里面的数据用 一个“\r\n”来区分,最后使用两个“\r\n”来区分数据

GET协议把数据放在了包头里面,POST协议把数据放在包头的最后面

GET提交的数据以“?”区分,参数之间以“&”进行连接

相应格式:

协议版本 状态码 状态码的原因短语 相应首部字段 主体

web框架 yuan功能总结

main.py: 启动文件,封装了socket

1 urls.py: 路径与视图函数映射关系  ---- url控制器

2 views.py 视图函数,固定有一个形式参数:environ -----视图函数,

3 templates文件夹: html文件   -----模板

4 models: 在项目启动前,在数据库中创建表结构    ----- 与数据库相关

Django的安装与启动
创建应用:python manage.py startapp blog
urlpatterns = [
re_path(r'^articles/2003/$', views.special_case_2003),
re_path(r'^articles/([0-9]{4})/$', views.year_archive),
re_path(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
re_path(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
] 有名分组:在组前面加上?P<组名> 即可,在传参时的形参必须是“组名”,否则会出错
 

命名空间:namespace
app01.urls:
需要加上
app_name = "app01"
urlpatterns=[
re_path(r'^index/',views.index,name="index"),
] 同理在ap02.urls加上相同的配置 views.py:
def index(request):
return HttpResponse(reverse("app01:index"))
需要加上反向解析

注册自定义转换器
先建一个类
class FourDigitYearConverter:
regex = '[0-9]{2}' #正则表达式的公式 def to_python(self,value):
return int(value) def to_url(self,value):
return '%04d' % value

在项目中注册转换器
# 注册定义的url转换器
register_converter(FourDigitYearConverter,'mm') #FourDigitYearConverter : 为以上类名

之后在urls里可以直接path使用
path('articles/<mm:month>/',views.month_archive)


模板语法 只有两个
1.{{}}
可以在
return render(request,'index.html',locals()) 这样就把该函数里的全部全局变量都传过去了
同时在index.html可以通过 . 来过去数据 如一个数组l=【‘123’,‘456’,‘789’】 ,在html可以通过l.2 获取到数据456

2{%%}
{%if%} {%endif%} 自定义标签与过滤器
1.在settings的INSTALLED_APPS加上当前app的名称,不然django无法找到自定义的simple_tag.
2.在app文件夹里面添加templatetags模块(模块名只能是templatetags)
3.在templatetags里面创建任意py文件
4.在该py文件里面引入
from django import template
register = template.Library()  # 固定名字
@register.filter          #加上装饰器,这个为模板过滤器
def filter_multi(x,y):
return x*y @register.simple_tag #标签过滤器
def filter_tag(x,y):
return x*y
5.在html文件里面读取该过滤器
{%load py的文件名%}
6.使用
{{ 2 | filter_multi:5 }}

{% filter_tag 5 6 %}

继承:extends
在一个base.html 里面把模板写好
在另一个html里面引入base.html
{% extends "base.html" %}
这时候可以在下面继续添加block里面的内容
{{% block title %}
<title>第一个</title>
{% endblock title%}

模型层ORM
ORM 对象-关系-映射
通过编写ORM层,控制pysql转换成db语句,再去控制db数据库。py文件里面通过创建一个类 生成表模型
1.创建模型
from django.db import models

# Create your models here.

class Book(models.Model):
id = models.AutoField(primary_key=True)
title=models.CharField(max_length=32)
state=models.BooleanField()
pub_date=models.DateField()
price=models.DecimalField(max_digits=8,decimal_places=2)
publish=models.CharField(max_length=32)

创建一个app,然后在app项目文件下的models下创建类

2.配置链接数据库settings

在项目文件下的settings文件设置下,设置数据库信息

DATABASES = {
'default':{
'ENGINE':'django.db.backends.mysql',
'NAME':'bms', #创建数据库名字
'USER':'root',         #链接数据库用户名
'PASSWORD':'',         #链接数据库密码
"HOST":'127.0.0.1',      #目标数据库地址
'PORT':3306           #目标数据库端口
}
}

  

3.确认信息

①在项目app文件下的__init__插入代码:
import pymysql

pymysql.install_as_MySQLdb()

②确保配置文件中的INSTALLED_APPS中写入我们创建的app名称

如在installed_apps 下添加app文件名

最后,可以进行数据迁移
python manage.py makemigrations
python manage.py migrate

  


数据库的建立create:
方式一:
book_obj = Book.objects.create(title='第一个数据库',state=True,price=500,pub_date="2012-12-12",publish='人民出版社')    #里面的数据格式需要与建立时的数据格式一致

方式二:
book_obj = Book(title='方式二',publish='机械出版社',state=True,pub_date="2010-12-11",price=10.12)
book_obj.save()                    #需要多一个save
 
查询表:
Django 自己生成的一个数据对象:QuerySet: [obj1,obj2,obj3....]
可以通过语句Book.object ---> 生成QuerySet数据
Book.object.all() 可以读取所有的数据

values方法: 返回和调用都是QuerySet
book_obj = Book.objects.values('price')
相当于
list = []
for obj in QuerySet:
  list.append{'price':obj['price']}
  .... #如果在values后面加值,就继续append values_list方法:  
返回和调用都是QuerySet
book_obj = Book.objects.values_list('price')


distinct:去重 从返回结果中剔除重复纪录

表的查询

一对多的查询:
A---B
如果关联表在A表中:
A----->B :正向查询
反过来通过B去查A 则是反向查询,主要看关联表在哪张表里面
正向查询:看字段
反向查询:看表名:表名小写__set.all() 聚合与分组查询
关键字:
annotate
总结 跨表的分组查询的模型:
# 每一个后表模型.objects.values("pk").annotate(聚合函数(关联表__统计字段))
 

AJAX
特点:
1.使用JavaScript向服务器发送异步请求
2.局部刷新
$(".Ajax").click(function () {
$.ajax({
url:"/test_ajax/", //请求地址
type:"get", //请求的类型poet或者是get
success:function (data) {
$(".haha").html(data)
console.log(data)
}
})
}) 数据之间的传输 通过使用json序列化
在py里面使用json.dump序列化
在Ajax里面使用JSON.parse 反序列化进行解析 利用Form表单进行文件上传
def file_put(request):
if request.method=="POST":
print('')
print(request.POST)
print(request.FILES) file_obj = request.FILES.get("tou") with open(file_obj.name,'wb') as f:
for i in file_obj:
f.write(i) return HttpResponse('OK') return render(request, "file_put.html")
批量导入数据库的数据:
'''
批量导入数据: Booklist=[]
for i in range(100):
book = Book(user="book_%s"%i,pwd=i*i)
Booklist.append(book)
Book.objects.bulk_create(Booklist)
'''

分页器:

book_list = Book.objects.all()

    paginator = Paginator(book_list,10)

    print("count:", paginator.count)  # 数据总数
print("num_pages", paginator.num_pages) # 总页数
print("page_range", paginator.page_range) # 页码的列表 page1=paginator.page(4) #第4页的page对象数据
for i in page1: #遍历
print(i) print(page1.object_list) #直接拿出该page的所有对象   
  #捕捉EmptyPage错误信息时做的处理
  try:
  current_page = int(request.GET.get("page",1))
  page1 = paginator.page(current_page)
  except EmptyPage as e:
  page1 = paginator.page(1)
 
 print(page2.has_next())            #是否有下一页
print(page2.next_page_number()) #下一页的页码
print(page2.has_previous()) #是否有上一页
print(page2.previous_page_number()) #上一页的页码

form组件

form.is_valid()   #:返回布尔值
form.cleaned_data #:{"name":"yuan","email":"123@qq.com"} 返回匹配成功的字典
form.errors #返回对应类字段的错误信息 :{"name":[".........."]}

from django.forms import widgets
class UserForm(forms.Form):                              #用于认证用
name = forms.CharField(max_length=32,label="用户名", widget=widgets.TextInput(attrs={"class":"form-control"}),error_messages={“required”:“该字段不能为空”}) #attr即为修改样式,error_message修改默认的错误信息,必须为required这个键名
pwd = forms.CharField(min_length=4)
r_pwd = forms.CharField(min_length=4)
email = forms.CharField()
tel = forms.CharField(min_length=4,max_length=32) def form_test(request):
if request.method == 'POST':
form = UserForm(request.POST)
if form.is_valid(): #校验是否验证通过,同时会把错误、正确的信息放在两个字典里面
print(form.cleaned_data)
else:
print(form.cleaned_data)
print(form.errors) # ErrorDict : {"校验错误的字段":["错误信息",]}
print(form.errors.get("name")) # ErrorList ["错误信息",]
return HttpResponse("OK")
form = UserForm()
return render(request, "form_test.html", locals()) form = UserForm() return render(request,"form_test.html")

在html里面想打印错误信息,可以{{form.name.errors}}  这样可以获取name里的错误信息

利用form表单组件 进行文件上传,使用FormData

$(".login_btn").click(function () {
var form_data = new FormData(); //首先实例化一个FormData
form_data.append("user",$("#id_user").val()) //再往里面添加数据
form_data.append("pwd",$("#id_pwd").val())
form_data.append("r_pwd",$("#id_r_pwd").val())
form_data.append("email",$("#id_email").val())
form_data.append("img",($("#avater")[0].files[0])) //该为文件,主要是传它才使用FormData,不然不用这么麻烦
form_data.append("csrfmiddlewaretoken",$("[name='csrfmiddlewaretoken']").val()) $.ajax({
url:"",
type:"post",
contentType:false, //必须设置这两个值
processData:false,
data:form_data, //最后把这个对象传给data
success:function (data) {
console.log(data)
}
})
})

局部钩子

在规则里面class 添加一个方法"clean_%s"name

 def clean_tel(self):
val = self.cleaned_data.get('tel') if len(val) == 11:
return val
else:
raise ValidationError("手机号格式错误")
form.is_valid--》self.errors-->self.full_clean--》self._clean_fields()
依次校验每个字段,之后再走钩子去判断里面有没有clean_%s 用户自定义的方法
if hasattr(self, 'clean_%s' % name):
value = getattr(self, 'clean_%s' % name)()
self.cleaned_data[name] = value

全局钩子

    def clean(self):
pwd = self.cleaned_data.get('pwd')
r_pwd = self.cleaned_data.get('r_pwd') if pwd and r_pwd:
if pwd == r_pwd:
return self.cleaned_data
else:
raise ValidationError('两次密码不一致!')
else:
return self.cleaned_data

视图函数 form_test.html

<div class="container">
<form action="" method="post">
{% csrf_token %}
<div class="row">
<div>
<p>
{{ form.name.label }}{{ form.name }}<span>{{ form.name.errors }}</span><span class="has-error pull-right">{{ errors.0 }}</span> #errors类 自己写
</p>
</div>
<div>
<p>
{{ form.pwd.label }}{{ form.pwd }}<span>{{ form.pwd.errors }}</span>
</p>
</div>
<div>
<p>
{{ form.r_pwd.label }}{{ form.r_pwd }}<span>{{ form.r_pwd.errors }}</span><span class="pull-right error">{{ errors.0 }}</span>
</p>
</div>
<div>
<p>
{{ form.email.label }}{{ form.email }}<span>{{ form.email.errors }}</span>
</p>
</div>
<div>
<p>
{{ form.tel.label }}{{ form.tel }}<span>{{ form.tel.errors }}</span>
</p>
</div>
<input type="submit" value="提交">

cookie:具体一个浏览器针对一个服务器存储key-value({})

获取cookie:

cookie 信息储存在request.COOKIE

第六章Django的更多相关文章

  1. 《Django By Example》第六章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:无他,祝大家年会都中奖!) 第六章 ...

  2. 第二十二章 Django会话与表单验证

    第二十二章 Django会话与表单验证 第一课 模板回顾 1.基本操作 def func(req): return render(req,'index.html',{'val':[1,2,3...]} ...

  3. 第六章、Cookies和Session

    目录 第六章.Cookies和Session 一.来源 二.cookie工作原理 工作原理: 三.session的工作原理 工作原理: 四.如何操作cookie 服务端常见的cookie操作 五.案例 ...

  4. 第六章、forms组件

    目录 第六章.forms组件 一.注册功能手写 二.forms组件完整写法 基本使用 三.forms组件前端渲染标签组件 三.forms组件其他知识点 在python console测试 校验数据 f ...

  5. 第六章、ajax方法以及序列化组件

    目录 第六章.ajax方法 一.choice参数介绍 二.MTV与MVC模型 三.ajax方法 四.案例 五.Ajax传json格式的数据 六. AJAX传文件 代码如下 ajax传文件需要注意的事项 ...

  6. 精通Web Analytics 2.0 (8) 第六章:使用定性数据解答”为什么“的谜团

    精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第六章:使用定性数据解答"为什么"的谜团 当我走进一家超市,我不希望员工会认出我或重新为我布置商店. 然而, ...

  7. 《Entity Framework 6 Recipes》中文翻译系列 (30) ------ 第六章 继承与建模高级应用之多对多关联

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第六章  继承与建模高级应用 现在,你应该对实体框架中基本的建模有了一定的了解,本章 ...

  8. 《Entity Framework 6 Recipes》中文翻译系列 (37) ------ 第六章 继承与建模高级应用之独立关联与外键关联

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 6-13  在基类中应用条件 问题 你想从一个已存在的模型中的实体派生一个新的实体, ...

  9. KnockoutJS 3.X API 第六章 组件(5) 高级应用组件加载器

    无论何时使用组件绑定或自定义元素注入组件,Knockout都将使用一个或多个组件装载器获取该组件的模板和视图模型. 组件加载器的任务是异步提供任何给定组件名称的模板/视图模型对. 本节目录 默认组件加 ...

随机推荐

  1. C#的ArrayList与JS的push,转字符串逗号分隔

    拼接字符串是常用的基本代码,但是还是有很多人习惯用"+"拼接字符串,这样做有以下缺点: 1)为了去掉尾部(或头部)分隔符,写法复杂 2)容易出现BUG报错,比如空值 C#中推荐大家 ...

  2. malloc/free与new/delete的区别与联系

    相同点:(1)都是申请内存,释放内存,free和delete可以释放NULL指针:(2)都必须配对使用,这里的配对使用,可不能理解为一个new/malloc就对应一个delete/free,而是指在作 ...

  3. 棋盘(noip2017普及组)

    题目描述 有一个m \times mm×m的棋盘,棋盘上每一个格子可能是红色.黄色或没有任何颜色的.你现在要从棋盘的最左上角走到棋盘的最右下角. 任何一个时刻,你所站在的位置必须是有颜色的(不能是无色 ...

  4. reinterpret_cast

    reinterpret_cast强制类型转换符 用法: new_type a = reinterpret_cast <new_type> (value) 将value的值转成new_typ ...

  5. springboot +redis配置

    springboot +redis配置 pom依赖 <dependency> <groupId>org.springframework.boot</groupId> ...

  6. MYSQL ini 配置文件详解及性能优化方案

    my.ini分为两块:Client Section和Server Section.   Client Section用来配置MySQL客户端参数.   要查看配置参数可以用下面的命令: show va ...

  7. C# 比较和排序(IComparable和IComparer以及它们的泛型实现)

    准备工作: 1.创建实体类:ClassInfo,默认想要对其按照班级学生数量进行排序 public class ClassInfo  { /// <summary> /// 班级名称 // ...

  8. 报错【org.springframework.validation.BeanPropertyBindingResult】

    报错内容:org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'price ...

  9. 从零开始写自己的PHP框架系列教程[前言]

    我觉得程序员进步的理由:多看->多写->多总结 我自我介绍下,我不是程序员,但是我爱编程,作为业余程序员自己写框架让人感到兴奋的,目前有很多框架(js有jQuery.Express.soc ...

  10. 给PostgreSQL添加MySQL的unix_timestamp与from_unixtime函数

    MySQL的2个常用函数unix_timestamp()与from_unixtime PostgreSQL并不提供,但通过PostgreSQL强大的扩展性可以轻松的解决问题. 话说远在天边,尽在眼前, ...