django知识回顾

Posted karina梅梅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django知识回顾相关的知识,希望对你有一定的参考价值。

一、web框架

1、web框架本质

众所周知,对于所有的web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端

1、浏览器(socket客户端)
2、发送IP和端口:http://www.baidu.com:80/index/
3、请求方式:
    GET:请求头:  如:http1.1 /index?p=123
        请求体:  无内容

    POSt:请求头   http1.1 /index?p=123
          请求体  

4、接收响应
普通响应:页面直接显示 
重定向响应:再起一次Http请求


服务器(socket服务端)
1、启动并监听ip和端口,等待用户连接
接收请求进行处理,并返回
普通返回:
响应头:
        Access-Control-Allow-Origin:*
        Cache-Control:max-age=600
        Date:Mon, 19 Jun 2017 00:57:43 GMT
        Expires:Mon, 19 Jun 2017 01:07:43 GMT
        Last-Modified:Wed, 24 May 2017 01:51:55 GMT
        Server:GitHub.com
        X-GitHub-Request-Id:C495:5EBC:8739EF:B817EE:59472187

响应体:
        <html>
        ....
        </html>

重定向返回:
    响应头:
            LOCATION: \'http://www.baidu.com\'
            Access-Control-Allow-Origin:*
            Cache-Control:max-age=600
            Date:Mon, 19 Jun 2017 00:57:43 GMT
            Expires:Mon, 19 Jun 2017 01:07:43 GMT
            Last-Modified:Wed, 24 May 2017 01:51:55 GMT
            Server:GitHub.com
            X-GitHub-Request-Id:C495:5EBC:8739EF:B817EE:59472187
View Code

WSGI(Web Sever Gateway Interface)是一种规范,它定义了使用python编写的web app与web server之间接口格式,
实现web app与web server间的解耦

2、自定义Web框架

通过python标准库提供的wsgiref模块开发一个自己的Web框架

from wsgiref.simple_server import make_server
 
def index():
    return \'index\'
 
def login():
    return \'login\'
 
def routers():
     
    urlpatterns = (
        (\'/index/\',index),
        (\'/login/\',login),
    )
     
    return urlpatterns
 
def RunServer(environ, start_response):
    start_response(\'200 OK\', [(\'Content-Type\', \'text/html\')])
    url = environ[\'PATH_INFO\']
    urlpatterns = routers()
    func = None
    for item in urlpatterns:
        if item[0] == url:
            func = item[1]
            break
    if func:
        return func()
    else:
        return \'404 not found\'
     
if __name__ == \'__main__\':
    httpd = make_server(\'\', 8000, RunServer)
    print "Serving HTTP on port 8000..."
    httpd.serve_forever()
Views
HTML:
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>Index</h1>

</body>
</html>

HTML:
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <form>
        <input type="text" />
        <input type="text" />
        <input type="submit" />
    </form>
</body>
</html>
html

对于上述代码,虽然可以返回给用户html的内容以实现复杂的页面,但是还是存在问题:如果给用户返回动态内容
自定义一套特殊的语法,进行替换
使用开源jinja2,遵循其指定语法

from wsgiref.simple_server import make_server
from jinja2 import Template
 
 
def index():
    # return \'index\'
 
    # template = Template(\'Hello {{ name }}!\')
    # result = template.render(name=\'John Doe\')
 
    f = open(\'index.html\')
    result = f.read()
    template = Template(result)
    data = template.render(name=\'John Doe\', user_list=[\'alex\', \'eric\'])
    return data.encode(\'utf-8\')
 
 
def login():
    # return \'login\'
    f = open(\'login.html\')
    data = f.read()
    return data
 
 
def routers():
 
    urlpatterns = (
        (\'/index/\', index),
        (\'/login/\', login),
    )
 
    return urlpatterns
 
 
def run_server(environ, start_response):
    start_response(\'200 OK\', [(\'Content-Type\', \'text/html\')])
    url = environ[\'PATH_INFO\']
    urlpatterns = routers()
    func = None
    for item in urlpatterns:
        if item[0] == url:
            func = item[1]
            break
    if func:
        return func()
    else:
        return \'404 not found\'
 
 
if __name__ == \'__main__\':
    httpd = make_server(\'\', 8000, run_server)
    print "Serving HTTP on port 8000..."
    httpd.serve_forever()
    
Views
HTML:
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>{{name}}</h1>

    <ul>
        {% for item in user_list %}
        <li>{{item}}</li>
        {% endfor %}
    </ul>

</body>
</html>
html

遵循jinja2的语法规则,其内部会对指定的语法进行相应的替换,
从而达到动态的返回内容。

 

二、DjangoWeb框架

1、介绍Django

django:是一个由python写成的开放源代码的Web应用框架。

1、django
    #安装: pip3 install django
      添加环境变量

    创建project 
       命令:django-admin startproject mysite
       ---mysite

          ---settings.py
          ---url.py
          ---wsgi.py
      ---- manage.py(启动文件)
      
      
     创建APP       
      python mannage.py startapp  app01
      project
            - app01
                - admin   Django自带后台管理相关配置
                - modal   写类,根据类创建数据库表
                - test    单元测试
                - views   业务处理

   
2、配置文件

a: 静态文件:
在settings里修改添加,放css,js,image等文件
创建static文件夹

STATIC_URL = \'/static/\'  # 相当于别名
STATICFILES_DIRS = [
        os.path.join(BASE_DIR,\'static\'), #切记一定加逗号
]

b:模板:
在settings里修改,放HTML文件
 TEMPLATE_DIRS = (
        os.path.join(BASE_DIR,\'templates\')
    )  
   
   
c:数据库:
# django支持sqlite,mysql, oracle,postgresql数据库
# django默认使用sqlite的数据库,默认自带sqlite的数据库驱动 , 引擎名称:django.db.backends.sqlite3
# 由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替
# 设置放置的与project同名的配置的 __init__.py文件中
 
__init__.py 导入
 
import pymysql
pymysql.install_as_MySQLdb() 


# 在settings 中修改DATABASES

DATABASES = {
    \'default\': {
        \'ENGINE\': \'django.db.backends.mysql\',
        \'NAME\': \'dbname\',   # 数据库名称
        \'USER\': \'root\',     # 用户名
        \'PASSWORD\': \'xxx\',  # 密码
        \'HOST\': \'\',         # IP,留空默认localhost
        \'PORT\': \'\',         # 端口
    }
}  

d:新增app
   INSTALLED_APPS = [
    \'django.contrib.admin\',
    \'django.contrib.auth\',
    \'django.contrib.contenttypes\',
    \'django.contrib.sessions\',
    \'django.contrib.messages\',
    \'django.contrib.staticfiles\',
    \'app01\',
    \'app02\',
]
   
  


3、路由关系
    from app01 import views
urlpatterns = [
    url(r\'^admin/\', admin.site.urls),
    url(r\'^index.html$\', views.index),
]
    

    
4、视图函数
def index(request):
     request.method
     request.GET
     request.POST
                        
    return HttpResponse(\'字符串\')
    return redirect(\'URL\')
    return render(request,\'模板路径\',{})
    # 1. 获取模板+数据,渲染
    # 2. HttpReponse(...)
    
5、模板渲染
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>模板标记学习</h1>
<p>{{ name }}</p>
<p>{{ users.0 }}</p>   //索引取值
<p>{{ users.1 }}</p>   //索引取值
<p>{{ user_dict.k1 }}</p>
<p>{{ user_dict.k2 }}</p>

例子:

urlpatterns = [
           url(r\'^login/\', login),  #后面配函数
           url(r\'^index/\', index),
           ]

def login(request):
    """
    处理用户请求,并返回内容
    :param request: 用户请求相关的所有信息(对象)
    :return:
    """
     #字符串
    # return HttpResponse("这个世界很美好".encode("utf8"))  #第一种返回字符串类型

    #自动找到模板路径下的login.html文件,读取内容并返回给用户
    #模板路径的配置 render
    if request.method=="GET":
        return render(request,\'login.html\')

    else:
         #用户POST提交的数据(请求体)
          u=request.POST.get("user")
          p=request.POST.get("pwd")
          if u=="root" and  p=="123123":
              #登录成功
              return redirect("http:www.oldboyde.com")    #重定向
          else:
              #登录失败
              return render(request,"login.html",{\'msg\':\'用户名或密码错误\'})
        # return render(request,\'login.html\')  #参数是什么,就传什么参数,后面也可以加参数

    
login.html
        <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/commons.css">
</head>
<body>
<h1>用户登录</h1>
<form method="POST" action="/login/">
    <input type="text" name="user" />
    <input type="password" name="pwd" />
    <input type="submit" value="登录" />
    {{ msg }}
</form>
</body>
例子

2、 Ajax:

jQuery其实就是一个javascript的类库,其将复杂的功能做了上层封装,使得开发者可以在其基础上写更少的代码实现更多的功能。

jQuery 不是生产者,而是大自然搬运工。
jQuery Ajax本质 XMLHttpRequest 或 ActiveXObject

jQuery.ajax(...)

                部分参数:
                        url:请求地址
                       type:请求方式,GET、POST(1.9.0之后用method)
                    headers:请求头
                       data:要发送的数据
                contentType:即将发送信息至服务器的内容编码类型(默认: "application/x-www-form-urlencoded; charset=UTF-8")
                      async:是否异步
                    timeout:设置请求超时时间(毫秒)

                 beforeSend:发送请求前执行的函数(全局)
                   complete:完成之后执行的回调函数(全局)
                    success:成功之后执行的回调函数(全局)
                      error:失败之后执行的回调函数(全局)
                

                    accepts:通过请求头发送给服务器,告诉服务器当前客户端课接受的数据类型
                   dataType:将服务器端返回的数据转换成指定类型
                                   "xml": 将服务器端返回的内容转换成xml格式
                                  "text": 将服务器端返回的内容转换成普通文本格式
                                  "html": 将服务器端返回的内容转换成普通文本格式,在插入DOM中时,如果包含JavaScript标签,则会尝试去执行。
                                "script": 尝试将返回值当作JavaScript去执行,然后再将服务器端返回的内容转换成普通文本格式
                                  "json": 将服务器端返回的内容转换成相应的JavaScript对象
                                 "jsonp": JSONP 格式
                                          使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数

                                  如果不指定,jQuery 将自动根据HTTP包MIME信息返回相应类型(an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string
ajax
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .btn{
            display: inline-block;
            padding: 5px 10px;
            background-color: coral;
            color: white;
        }
    </style>
</head>
<body>
    <h1>jQuery Ajax</h1>
    <h3>GET请求</h3>
    <div>
        <a class="btn" onclick="AjaxSubmit1();">点我</a>
    </div>
    <h3>POST请求</h3>
    <div>
        <a class="btn" onclick="AjaxSubmit3();">点我</a>
    </div>
    <script>
        function  AjaxSubmit1() {
            $.ajax({
                url: \'/ajax1.html\',
                type:\'GET\',
                data: {\'p\':123},
                success:function (arg) {

                }
            })
        }        
View Code
1、 ajax参数
    url:
    type:
    data:
    1、value不能是字典 {k1:\'v1\',k2:[1,2,3,],k3; JSON.string}
    2、$(\'\').serilizer()
    dataType:"JSON", # text,html,xml
    单词太长了 traditional:
    success:function(arg) {
        #arg=>obj
    },
    error:function(){
    }
 
 
2、序列化
    JavaScript:
        JSON.parse()
        JSon.stringify()
     
    Django:
        json.dumps()
        json.loads()
        问题:
            serilize: model.TB.objects.all()
            json: model.TB.objects.value()
            json: model.TB.objects.value_list()

 3、路由系统

URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表;
你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。

a:单一路由对应	
url(r\'^index$\', views.index),
b:基于正则的路由
url(r\'^index/(\\d*)\', views.index),
url(r\'^manage/(?P<name>\\w*)/(?P<id>\\d*)\', views.manage),
c:添加额外的参数
url(r\'^manage/(?P<name>\\w*)\', views.manage,{\'id\':333}),
d:为路由映射设置名称(反向生成url)
url(r\'^home\', views.home, name=\'h1\'),
url(r\'^index/(\\d*)\', views.index, name=\'h2\'),

urls:
	url(r\'^index/(\\d+)/\',views.index,name="n1"),
	url(r\'^index/(?P<a1>\\d+)/\',views.index,name="n1"),

views:
	from django.urls import reverse    #根据名字反转成url
	def index(request,a1):    #一一对应关系
		user_list=[
			"alex","eric","tony"
    ]
    v=reverse("n1",args=(1,))    #args= 数字自己规定 写的是1 url也会体现出来
    and
	v=reverse("n1",kwargs={\'a1\':11111}) 
	print(v)
    return render(request,\'index.html\',{"user_list":user_list})

在html里写
	url(r\'^login/\',views.login,name=\'m1\'),
    <form method="POST" action="{% url "m1" %}">    /* 根据名称也可以反生url*/
	url(r\'^edit/(\\w+)/\', views.edit,name=\'n2\')
	<li>{{ i }}<a href="{% url \'n2\' i %}">| 编辑</a></li>    跳转的时候也可以做,不用写url
e:路由分发
如果映射url太多,全写一个在  urlpatterns 显得繁琐,so 路由分发应用而生

urls.py
	url(r\'^app01/\',include(\'app01.urls\')),

总路由:
	url(r\'^\',default), url不存在的话 可以默认写 or 跳转到index 的路径下
	url(r\'^\',views.index),  #路由默认不写 或者路由错误 直接执行index的函数
app01.urls.py
	url(r\'^index.html$\',views.index),
额外:
终止符:^edits$
伪静态:url(r’^edit/(\\w+).html$’,views.edit),

4、视图函数(CBV & FBV)

CBV:
	# from django.views import View     #导入一个 View 以便类继承

	# class Login(View): #继承一个特殊的类  View
	#     """
	#     提交方法
	#     get  查
	#     post  创建
	#     put   更新
	#     delete  删除
	#     """
	#
	#     def get(self,request):    #get请求取值
	#         return render(request,\'login.html\')
	#
	#     def post(self,request):   #post请求取值
	#         print(request.POST.get("user"))
	#         return HttpResponse("Login.post")


	urlpatterns = [
		url(r\'^admin/\', admin.site.urls),
		url(r\'^test.html$\',views.test),   #url对应函数
		url(r\'^login.html$\',views.Login.as_view()),   #url对应类
	]


	<!DOCTYPE html>
	<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>Title</title>
	</head>
	<body>
	<form method="POST" action="/login.html">
		<input type="text" name="user"/>
		<input type="submit" value="提交"/>
	</form>
	</body>
	</html>

5、ORM操作:

a.创建表
	from django.db import models


	class User_type(models.Model):
		uid = models.BigAutoField(primary_key=True)
		title = models.CharField(max_length=32)

	class User_info(models.Model):
		name = models.CharField(max_length=32)
		age = models.CharField(max_length=32)
		ut = models.ForeignKey("User_type")


	python manage.py makemigrations

	python manage.py migrate
---------------------其它---------------------

	class part(models.Model):
		cid = models.BigAutoField(primary_key=True)
		title = models.CharField(max_length=32,null=False)


	class student(models.Model):
		sid = models.BigAutoField(primary_key=True)
		name = models.CharField(max_length=32,null=False)
		pub_data=models.DateField()
		age = models.IntegerField(default=18)
		# 新增加的列 如果原先表里有值,写default
		ug = models.ForeignKey("part",null=True) #如果新增加外键,加null=True
	
	
b:ORM操作:
	基本操作:
	#增
	# models.User_type.objects.create(title="黑金用户")
		
	# obj = models.User_type(title="小白用户")
	# obj.save()

	#删
	#models.User_type.objects.filter(title="小白用户").delete()  # 删除指定条件的数据

	#改
	#models.User_type.objects.filter(title="黑金用户").update(title="黑卡用户")    # 修改指定条件的数据

	#查
	# models.User_type.objects.get(title="大白用户")      # 获取单条数据,不存在则报错(不建议)
	# models.User_type.objects.all()                     # 获取全部
	# models.User_type.objects.filter(title="小白用户")   # 获取指定条件的数据
	# models.User_type.objects.exclude(title="黄金用户")     # 排除指定条件的数据	

Django--ORM基本操作 请看我的另一篇博客:http://www.cnblogs.com/niejinmei/p/7089719.html

c:多对多操作 

    方法一:
        通过外键创建第三张表
    class Boy(models.Model):
        name = models.CharField(max_length=32)
     
    class Girl(models.Model):
        nick = models.CharField(max_length=32)
     
    class Love(models.Model):
        b = models.ForeignKey("Boy")
        g = models.ForeignKey("Girl")
         
        class Meta:
            unique_together = [
                ("b","g"),
            ]

    #表里插入数据

    objs = [
            models.Boy(name=\'方少伟\'),
            models.Boy(name=\'游勤斌\'),
            models.Boy(name=\'于浩\'),
            models.Boy(name=\'陈涛\'),
    ]
    models.Boy.objects.bulk_create(objs,4)

    result = [
        models.Girl(nick=\'于浩姐姐\'),
        models.Girl(nick=\'景甜\'),
        models.Girl(nick=\'刘亦非\'),
        models.Girl(nick=\'苍老师\'),
    ]
    models.Girl.objects.bulk_create(result, 4)

    models.Love.objects.create(b_id=1,g_id=1)
    models.Love.objects.create(b_id=1,g_id=2)
    models.Love.objects.create(b_id=1,g_id=3)
    models.Love.objects.create(b_id=2,g_id=4)


    ###################   查找和我有关系的女孩  四种方式 ################


    obj = models.Boy.objects.filter(name="方少伟").first()
    love_list = obj.love_set.all()
    for row in love_list:
       print(row.g.nick)

    love_list = models.Love.objects.filter(b__name="方少伟")
    for row in love_list:
        print(row.g.nick)


    #下面两个效果好

    love_list = models.Love.objects.filter(b__name="方少伟").values("g__nick")
    for item in love_list:
        print(item["g__nick"])   
        


    love_list = models.Love.objects.filter(b__name="方少伟").select_related("g")
    for obj in love_list:
        print(obj.g.nick)        
方法一
通过 ManyToManyField 创建第三张表
    class Boy(models.Model):
        name = models.CharField(max_length=32)
        m = models.ManyToManyField("Girl")
     
    class Girl(models.Model):
        nick = models.CharField(max_length=32)
    obj = models.Boy.objects.filter(name="方少伟").first()
        # print(obj.id,obj.name)

        # obj.m.add(2)
        # obj.m.add(1,3)
        # obj.m.add(*[4,])

        # obj.m.remove(2)
        # obj.m.remove(1,3)
        # obj.m.remove(*[4,])

        # obj.m.set([1,4,])


        # girl_list = obj.m.all()
        # girl_list = obj.m.filter(nick="苍老师")


        # obj.m.clear()

    obj = models.Girl.objects.filter(nick="苍老师").first()
    v = obj.boy_set.all()            
方法二
方式三:通过 外键 和 ManyToManyField 创建
    class Boy(models.Model):
        name = models.CharField(max_length=32)
        m = models.ManyToManyField("Girl",through="Love",through_fields=("b","g",))
     
    class Girl(models.Model):
        nick = mod

以上是关于django知识回顾的主要内容,如果未能解决你的问题,请参考以下文章

django知识回顾

$Django 路飞之小知识回顾,Vue之样式element-ui,Vue绑定图片--mounted页面挂载--路由携带参数

Django学习日记-08回顾--温故知新

如何在 Django Summernote 中显示编程片段的代码块?

django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段

django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段