Django Ajax jQuery实现网页动态更新的实例

<script type="text/javascript">
 window.jQuery || document.write("<script src='../static/js/jquery.min.js'>"   "<"   "/script>");
</script>
<script type="text/javascript">
 $(function() {

 var submit_form = function(e) {
  $.ajax({
 type : "GET",
 url : "/getdevjson?" Math.random(),
 data : {
 key: $('#searchContent').val()
 },
 dataType : "text",
 success : function(res){
   $('#searchContent').focus().select();
   //console.log(res);
 update(res);
   },
   error : function() {
 alert("处理异常返回!");}


 });

 return false;
 };
 $('#calculate').bind('click', submit_form);
 $('input[type=text]').bind('keydown', function(e) {
 if (e.keyCode == 13) {
 submit_form(e);
 }
 });
 $('#searchContent').focus();
 });
</script>


 <div class="divRight" id="divright1">
 <div class="divRight" style="height:70px; width:370px;">
<label id="lblSearch" class="cssLabelSearch">请输入查询key:</label>
<input id="searchContent" type="text" size="40"></input>
 <input id="calculate" type="button" value="确定" ></input>
</div>
 <br>
<label id="lbl1" class="cssLabelClient">节点信息</label>
<Textarea id="ClientInfoArea" readonly class="txtClientInfo"></Textarea>
</div>

jquery实现的ajax

图片 1图片 2

{% load staticfiles %}

<!DOCTYPE html>

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="{% static 'JS/jquery-3.1.1.js' %}"></script>
</head>
<body>

<button class="send_Ajax">send_Ajax</button>

<script>
      //$.ajax的两种使用方式:

      //$.ajax(settings);
      //$.ajax(url,[settings]);


       $(".send_Ajax").click(function(){

           $.ajax({
               url:"/handle_Ajax/",
               type:"POST",
               data:{username:"Yuan",password:123},

               success:function(data){
                   alert(data)
               },

                 //=================== error============

                error: function (jqXHR, textStatus, err) {

                        // jqXHR: jQuery增强的xhr
                        // textStatus: 请求完成状态
                        // err: 底层通过throw抛出的异常对象,值与错误类型有关
                        console.log(arguments);
                    },

                 //=================== complete============

                complete: function (jqXHR, textStatus) {
                    // jqXHR: jQuery增强的xhr
                    // textStatus: 请求完成状态 success | error
                    console.log('statusCode: %d, statusText: %s', jqXHR.status, jqXHR.statusText);
                    console.log('textStatus: %s', textStatus);
                },

                //=================== statusCode============
                statusCode: {
                    '403': function (jqXHR, textStatus, err) {
                        console.log(arguments);  //注意:后端模拟errror方式:HttpResponse.status_code=500
                     },

                    '400': function () {
                    }
                }

           })

       })

</script>
</body>
</html>

jquery实现的ajax

图片 3图片 4

import json

def index(request):

    return render(request,"index.html")

def handle_Ajax(request):

    username=request.POST.get("username")
    password=request.POST.get("password")

    print(username,password)

    return HttpResponse(json.dumps("Error Data!"))

views

views.py

urls.py中修改如下:

11.1 From

  Django会将表单的提交变得更加简单和安全,包括重构数据后在页面间传递,创建前端的HTML页面以及接收和处理客户端传来的数据。实施上,你只需要事先定义好form表单的各种属性,在前端页面简单调用即可。当然,Django为Form提供了许多属性,方便自定义,甚至你可以重写其中的一些方法。

from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
 url(r'^getdevjson$','dev.views.getdevjson',name='getdevjson'),
 url(r'^','dev.views.index',name='index'), 
 url(r'^admin/', include(admin.site.urls)),
)

5.1.2. 基于dispatch和继承实现用户登录代码

  1、写一个登录验证类

图片 5图片 6

class AuthView(object):
    def dispatch(self, request, *args, **kwargs):
        if not request.session.get('user_info'):
            return redirect('/login.html')
        res = super(AuthView,self).dispatch(request, *args, **kwargs)
        return res

CBV实现用户登录验证

2、修改views.py并继承验证

图片 7图片 8

from django.views import View

class Index(AuthView,View):

    def get(self, req):
        print(‘method is :‘   req.method)
        return render(req, ‘index.html‘)

    def post(self, req):
        print(‘method is :‘   req.method)
        return render(req, ‘index.html‘)
#继承AuthView验证类即可

CBV实现用户登录验证

def getdevjson(request):
 print 'get here'
 if ('key' in request.GET):
 searchkey = request.GET.get('key')
 return JsonResponse(search(searchkey))
 else:
 return HttpResponse('Sorry!')

 js实现局部刷新

图片 9图片 10

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <style>
        .error{
            color:red
        }
    </style>
</head>
<body>


<form class="Form">

    <p>姓名&nbsp;&nbsp;<input class="v1" type="text" name="username" mark="用户名"></p>
    <p>密码&nbsp;&nbsp;<input class="v1" type="text" name="email" mark="邮箱"></p>
    <p><input type="submit" value="submit"></p>

</form>

<script src="jquery-3.1.1.js"></script>

<script>

    $(".Form :submit").click(function(){

        flag=true;

        $("Form .v1").each(function(){

            var value=$(this).val();
            if (value.trim().length==0){
                 var mark=$(this).attr("mark");
                 var $span=$("");
                 $span.html(mark "不能为空!");
                 $span.prop("class","error");
                 $(this).after($span);

                 setTimeout(function(){
                      $span.remove();
                 },800);

                 flag=false;
                 return flag;

            }
        });
        return flag
    });


</script>


</body>
</html>

js实现局部刷新

前端网页修改

Django知识点汇总

views.py中的修改

{% url %}

引用路由配置的地址

图片 11图片 12

<form action="{% url "bieming"%}" >
          <input type="text">
          <input type="submit"value="提交">
          {%csrf_token%}
</form>

{% url %}标签使用

#calculate是一个按钮,点击动作绑定了提交函数submit_form,ajax的请求参数中,data中包含了查询参数,success是请求成功后的动作,注意返回的res需要进行json解析才可以正确使用:root = JSON.parse(jsondata);update(res)是一个更新网页内容的函数

8.2.1 GET请求

HTTP默认的请求方法就是GET

?

1
2
3
* 没有请求体
* 数据必须在1K之内!
* GET请求数据会暴露在浏览器的地址栏中

GET请求常用的操作:

图片 13图片 14

1. 在浏览器的地址栏中直接给出URL,那么就一定是GET请求
2. 点击页面上的超链接也一定是GET请求
3. 提交表单时,表单默认使用GET请求,但可以设置为POST

GET请求常用的操作:

返回字符串中,既可以使用from django.http import JsonResponse,也可以使用HttpResponse(json.dumps(res))

8.2 请求协议

请求协议的格式如下:

图片 15图片 16

请求首行;  // 请求方式 请求路径 协议和版本,例如:GET /index.html HTTP/1.1
请求头信息;// 请求头名称:请求头内容,即为key:value格式,例如:Host:localhost
空行;     // 用来与请求体分隔开
请求体。   // GET没有请求体,只有POST有请求体。为一个个键值对

实例:
GET请求:
    "GET /index.html http1.1rnUser-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x6..rnrnAccept-Encoding:gziprnrn"
POST请求:
    "POST /index.html http1.1rnUser-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x6..rnrnAccept-Encoding:gziprnrnuser=cqz&hobby=lihao"

请求头以rn划分
请求体以rnrn划分

请求协议格式

浏览器发送给服务器的内容就这个格式的,如果不是这个格式服务器将无法解读!在HTTP协议中,请求有很多请求方法,其中最为常用的就是GET和POST。

增加相应的请求处理函数:

csrf跨站请求伪造

方法一

图片 17图片 18

$.ajaxSetup({
    data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});

csrf跨站请求伪造

方法二:

图片 19图片 20

var formData=new FormData();

var username= $("#username").val();
var email= $("#emailsignup").val();
var csrf=$("[name='csrfmiddlewaretoken']").val();

formData.append("username",username);
formData.append("email",email);
formData.append("csrfmiddlewaretoken",csrf);

$.ajax({
               url:"/handle_Ajax/",
               type:"POST",
              data: formData,,

               success:function(data){
                   alert(data)
               },   

           })

csrf跨站请求伪造方法二

需要注意的是为了避免路由被覆盖,将index的路由配置尽量放置在最后一行。

示例:改密码

图片 21图片 22

@login_required
def set_password(request):
    user = request.user
    state = None
    if request.method == 'POST':
        old_password = request.POST.get('old_password', '')
        new_password = request.POST.get('new_password', '')
        repeat_password = request.POST.get('repeat_password', '')
        if user.check_password(old_password):
            if not new_password:
                state = 'empty'
            elif new_password != repeat_password:
                state = 'repeat_error'
            else:
                user.set_password(new_password)
                user.save()
                return redirect("/log_in/")
        else:
            state = 'password_error'
    content = {
        'user': user,
        'state': state,
    }
    return render(request, 'book/set_password.html', content)

View Code

 返回顶部

 

以上这篇Django Ajax jQuery实现网页动态更新的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

十、Django的用户认证

您可能感兴趣的文章:

十七、数据库性能相关

路由配置修改

九、COOKIE 与 SESSION

 8.5 HttpRequest 的方法

图片 23图片 24

方法                                 描述
__getitem__(key)    请求所给键的GET/POST值,先查找POST,然后是GET。 若键不存在,则引发异常KeyError 。该方法使用户可以以访问字典方式来访问一个 HttpRequest 实例。例如, request["foo"] 和先检查 request.POST["foo"] 再检查request.GET["foo"] 一 样。

has_key()                 返回 True 或 False , 标识 request.GET 或 request.POST 是否包含所给的 键。

get_full_path()          返回 path ,若请求字符串有效,则附加于其后。 例如,"/music/bands/the_beatles/?print=true" 。

is_secure()         如果请求是安全的,则返回 True 。 也就是说,请求是以HTTPS的形式提交的。

HttpRequest 的方法

返回顶部

5.2.1. 基本使用

1、使用方法为:urls.py 修改为如下:

图片 25图片 26

from django.conf.urls import url, include

# from django.contrib import admin
from mytest import views

urlpatterns = [
    # url(r‘^admin/‘, admin.site.urls),
    url(r‘^index/‘, views.index),
]

FBV中urls.py文件

2、views.py 修改为如下:

图片 27图片 28

from django.shortcuts import render


def index(req):
    if req.method == ‘POST‘:
        print(‘method is :‘   req.method)
    elif req.method == ‘GET‘:
        print(‘method is :‘   req.method)
    return render(req, ‘index.html‘)

#注意此处定义的是函数【def index(req):】

FBV中views.py文件

3、index.html

图片 29图片 30

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index</title>
</head>
<body>
    <form action="" method="post">
        <input type="text" name="A" />
        <input type="submit" name="b" value="提交" />
    </form>
</body>
</html>

index.html

中间件之process_template_responseprocess

process_template_response(self,request,response)

只有当views函数中返回的对象中具有render方法,是就会直接process_template_responseprocess

6、F查询和Q查询

图片 31图片 32

# F 使用查询条件的值,专门取对象中某列值的操作

    # from django.db.models import F
    # models.Tb1.objects.update(num=F('num') 1)


# Q 构建搜索条件
    from django.db.models import Q

    #1 Q对象(django.db.models.Q)可以对关键字参数进行封装,从而更好地应用多个查询
    q1=models.Book.objects.filter(Q(title__startswith='P')).all()
    print(q1)#[<Book: Python>, <Book: Perl>]

    # 2、可以组合使用&,|操作符,当一个操作符是用于两个Q的对象,它产生一个新的Q对象。
    Q(title__startswith='P') | Q(title__startswith='J')

    # 3、Q对象可以用~操作符放在前面表示否定,也可允许否定与不否定形式的组合
    Q(title__startswith='P') | ~Q(pub_date__year=2005)

    # 4、应用范围:

    # Each lookup function that takes keyword-arguments (e.g. filter(),
    #  exclude(), get()) can also be passed one or more Q objects as
    # positional (not-named) arguments. If you provide multiple Q object
    # arguments to a lookup function, the arguments will be “AND”ed
    # together. For example:

    Book.objects.get(
        Q(title__startswith='P'),
        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
    )

    #sql:
    # SELECT * from polls WHERE question LIKE 'P%'
    #     AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')

    # import datetime
    # e=datetime.date(2005,5,6)  #2005-05-06

    # 5、Q对象可以与关键字参数查询一起使用,不过一定要把Q对象放在关键字参数查询的前面。
    # 正确:
    Book.objects.get(
        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
        title__startswith='P')
    # 错误:
    Book.objects.get(
        question__startswith='P',
        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))

F查询和Q查询

 返回顶部

 

十四、信号

Django中提供了“信号调度”,用于在框架执行操作时解耦。通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒一些接受者。

1、Django内置信号

图片 33图片 34

Model signals
        pre_init                    # django的modal执行其构造方法前,自动触发
        post_init                   # django的modal执行其构造方法后,自动触发
        pre_save                    # django的modal对象保存前,自动触发
        post_save                   # django的modal对象保存后,自动触发
        pre_delete                  # django的modal对象删除前,自动触发
        post_delete                 # django的modal对象删除后,自动触发
        m2m_changed                 # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发
        class_prepared              # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发
    Management signals
        pre_migrate                 # 执行migrate命令前,自动触发
        post_migrate                # 执行migrate命令后,自动触发
    Request/response signals
        request_started             # 请求到来前,自动触发
        request_finished            # 请求结束后,自动触发
        got_request_exception       # 请求异常后,自动触发
    Test signals
        setting_changed             # 使用test测试修改配置文件时,自动触发
        template_rendered           # 使用test测试渲染模板时,自动触发
    Database Wrappers
        connection_created          # 创建数据库连接时,自动触发

Django内置信号说明

 

对于Django内置的信号,仅需注册指定信号,当程序执行相应操作时,自动触发注册函数:

图片 35图片 36

    from django.core.signals import request_finished
    from django.core.signals import request_started
    from django.core.signals import got_request_exception

    from django.db.models.signals import class_prepared
    from django.db.models.signals import pre_init, post_init
    from django.db.models.signals import pre_save, post_save
    from django.db.models.signals import pre_delete, post_delete
    from django.db.models.signals import m2m_changed
    from django.db.models.signals import pre_migrate, post_migrate

    from django.test.signals import setting_changed
    from django.test.signals import template_rendered

    from django.db.backends.signals import connection_created


    def callback(sender, **kwargs):
        print("xxoo_callback")
        print(sender,kwargs)

    xxoo.connect(callback)
    # xxoo指上述导入的内容

注册信号

图片 37图片 38

from django.core.signals import request_finished
from django.dispatch import receiver

@receiver(request_finished)
def my_callback(sender, **kwargs):
    print("Request finished!")

信号应用举例

2、自定义信号

a. 定义信号

图片 39图片 40

import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])

定义信号

b. 注册信号

图片 41图片 42

def callback(sender, **kwargs):
            print("callback")
            print(sender,kwargs)

        pizza_done.connect(callback)

注册信号

c. 触发信号

图片 43图片 44

from 路径 import pizza_done

        pizza_done.send(sender='seven',toppings=123, size=456)

触发信号

由于内置信号的触发者已经集成到Django中,所以其会自动调用,而对于自定义信号则需要开发者在任意位置触发。

 

返回顶部

10.1.4 user对象的 is_authenticated()

要求:

?

1
2
3
1  用户登陆后才能访问某些页面,
2  如果用户没有登录就访问该页面的话直接跳到登录页面
3  用户在跳转的登陆界面中完成登陆后,自动访问跳转到之前访问的地址

方法1:

?

1
2
3
def my_view(request):
  if not request.user.is_authenticated():
    return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))

方法2:login_required函数

django已经为我们设计好了一个用于此种情况的装饰器:login_requierd()

?

1
2
3
4
5
from django.contrib.auth.decorators import login_required
     
@login_required
def my_view(request):
  ...

若用户没有登录,则会跳转到django默认的 登录URL '/accounts/login/ ' (这个值可以在settings文件中通过LOGIN_URL进行修改)。并传递  当前访问url的绝对路径 (登陆成功后,会重定向到该路径)。 

10.3 User 对象方法  

中间件之process_view执行过程:

图片 45

当最后一个中间的process_request到达路由关系映射之后,返回到中间件1的process_view,然后依次往下,到达views函数,最后通过process_response依次返回到达用户

 11.2.1ModelForm参数和使用

图片 46图片 47

ModelForm
    a.  class Meta:
            model,                           # 对应Model的
            fields=None,                     # 字段
            exclude=None,                    # 排除字段
            labels=None,                     # 提示信息
            help_texts=None,                 # 帮助提示信息
            widgets=None,                    # 自定义插件
            error_messages=None,             # 自定义错误信息(整体错误信息from django.core.exceptions import NON_FIELD_ERRORS)
            field_classes=None               # 自定义字段类 (也可以自定义字段)
            localized_fields=('birth_date',) # 本地化,如:根据不同时区显示数据
            如:
                数据库中
                    2016-12-27 04:10:57
                setting中的配置
                    TIME_ZONE = 'Asia/Shanghai'
                    USE_TZ = True
                则显示:
                    2016-12-27 12:10:57
    b. 验证执行过程
        is_valid -> full_clean -> 钩子 -> 整体错误

    c. 字典字段验证
        def clean_字段名(self):
            # 可以抛出异常
            # from django.core.exceptions import ValidationError
            return "新值"
    d. 用于验证
        model_form_obj = XXOOModelForm()
        model_form_obj.is_valid()
        model_form_obj.errors.as_json()
        model_form_obj.clean()
        model_form_obj.cleaned_data
    e. 用于创建
        model_form_obj = XXOOModelForm(request.POST)
        #### 页面显示,并提交 #####
        # 默认保存多对多
            obj = form.save(commit=True)
        # 不做任何操作,内部定义 save_m2m(用于保存多对多)
            obj = form.save(commit=False)
            obj.save()      # 保存单表信息
            obj.save_m2m()  # 保存关联多对多信息

    f. 用于更新和初始化
        obj = model.tb.objects.get(id=1)
        model_form_obj = XXOOModelForm(request.POST,instance=obj)
        ...

        PS: 单纯初始化
            model_form_obj = XXOOModelForm(initial={...})

ModelForm参数和使用

 

 三、URL路由系统(URLconf)

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

图片 48图片 49

 '''

    urlpatterns = [
         url(正则表达式, views视图函数,参数,别名),
]


参数说明:

    一个正则表达式字符串
    一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
    可选的要传递给视图函数的默认参数(字典形式)
    一个可选的name参数

    '''

URLconf说明

运行WSGI服务

我们先编写hello.py,实现Web应用程序的WSGI处理函数:

?

1
2
3
4
5
# hello.py
 
def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return '<h1>Hello, web!</h1>'

然后,再编写一个server.py,负责启动WSGI服务器,加载application()函数:

?

1
2
3
4
5
6
7
8
9
10
11
# server.py
# 从wsgiref模块导入:
from wsgiref.simple_server import make_server
# 导入我们自己编写的application函数:
from hello import application
 
# 创建一个服务器,IP地址为空,端口是8000,处理函数是application:
httpd = make_server('', 8000, application)
print ("Serving HTTP on port 8000..."
# 开始监听HTTP请求:
httpd.serve_forever()

确保以上两个文件在同一个目录下,然后在命令行输入python server.py来启动WSGI服务器:

图片 50

 

注意:如果8000端口已被其他程序占用,启动将失败,请修改成其他端口。

启动成功后,打开浏览器,输入http://localhost:8000/,就可以看到结果了:

图片 51图片 52

复制代码

整个application()函数本身没有涉及到任何解析HTTP的部分,也就是说,底层代码不需要我们自己编写,
我们只负责在更高层次上考虑如何响应请求就可以了。

application()函数必须由WSGI服务器来调用。有很多符合WSGI规范的服务器,我们可以挑选一个来用。

Python内置了一个WSGI服务器,这个模块叫wsgiref    


application()函数就是符合WSGI标准的一个HTTP处理函数,它接收两个参数:

        //environ:一个包含所有HTTP请求信息的dict对象;

        //start_response:一个发送HTTP响应的函数。

在application()函数中,调用:

start_response('200 OK', [('Content-Type', 'text/html')])

就发送了HTTP响应的Header,注意Header只能发送一次,也就是只能调用一次start_response()函数。
start_response()函数接收两个参数,一个是HTTP响应码,一个是一组list表示的HTTP Header,每
个Header用一个包含两个str的tuple表示。

通常情况下,都应该把Content-Type头发送给浏览器。其他很多常用的HTTP Header也应该发送。

然后,函数的返回值b'<h1>Hello, web!</h1>'将作为HTTP响应的Body发送给浏览器。

有了WSGI,我们关心的就是如何从environ这个dict对象拿到HTTP请求信息,然后构造HTML,
通过start_response()发送Header,最后返回Body。

复制代码

注意

 

回到顶部

 十七、数据库性能相关

select_related 与 prefetch_related 区别

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
user_list = models.UserInfo.objects.all()
    for row in user_list:
        # 只去取当前表数据
 
select_related,主动连表查询【FK】
     
    user_list = models.UserInfo.objects.all().select_related('FK字段')
    for row in user_list:
        # 只去取当前表数据和FK表关联字段
 
 
    user_list = models.UserInfo.objects.values(...)
    for row in user_list:
        # 只去取当前表数据和FK表关联字段
 
    ==》 连表降低性能
 
prefetch_related 被动连表
    user_list = models.UserInfo.objects.all().prefetch_related('FK字段')
 
    # [obj,obj,obj]
    # 查询用户表models.UserInfo.objects.all() 1000
    # 把用户表中所有的ut_id拿到, 用户类型ID [1,2,3]
    # 把用户表中所有的ut_id拿到, 用户类型ID [21,21,31]
    # select * from UsetType where id in [1,2,3]
    # select * from xx where id in [21,21,31]
    user_list = models.UserInfo.objects.all().prefetch_related('ut','xx')
    for row in user_list:
        print(row.name, row.pwd, row.ut.caption)
补充:
    # [obj,obj,obj]
    # user_list = models.UserInfo.objects.all().only('name')   # 只取某个字段 select name from userinfo
    # user_list = models.UserInfo.objects.all().defer('name')  # 排除当前字段
    # for row in user_list:
    #     print(row.pwd)

select_related,主动连表查询【FK】,当连表不多时用select_related查询

prefetch_related 被动连表,当连表较多时,用prefetch_related查询

 返回顶部

未添加:

自定义分页、验证码、头像预览、富文本编辑框

 

 

 

 

 

5.2 FBV(function base views)

FBV(function base views) 就是在视图里使用函数处理请求。

十四、信号

6.1、创建表

3.3 URLconf 在什么上查找

URLconf 在请求的URL 上查找,将它当做一个普通的Python 字符串。不包括GET和POST参数以及域名。

例如,http://www.example.com/myapp/ 请求中,URLconf 将查找myapp/

http://www.example.com/myapp/?page=3 请求中,URLconf 仍将查找myapp/

URLconf 不检查请求的方法。换句话讲,所有的请求方法 —— 同一个URL的POSTGETHEAD等等 —— 都将路由到相同的函数。

 redirect函数

图片 53图片 54

-----------------------------------url.py

 url(r"login",   views.login),
 url(r"yuan_back",   views.yuan_back),

-----------------------------------views.py
def login(req):
    if req.method=="POST":
        if 1:
            # return redirect("/yuan_back/")
            name="yuanhao"

            return render(req,"my backend.html",locals())

    return render(req,"login.html",locals())


def yuan_back(req):

    name="苑昊"

    return render(req,"my backend.html",locals())

-----------------------------------login.html

<form action="/login/" method="post">
    <p>姓名<input type="text" name="username"></p>
    <p>性别<input type="text" name="sex"></p>
    <p>邮箱<input type="text" name="email"></p>
    <p><input type="submit" value="submit"></p>
</form>
-----------------------------------my backend.html
<h1>用户{{ name }}你好</h1>

#总结: render和redirect的区别:
#   1 if render的页面需要模板语言渲染,需要的将数据库的数据加载到html,那么所有的这一部分
#     除了写在yuan_back的视图函数中,必须还要写在login中,代码重复,没有解耦.

#   2 the most important: url没有跳转到/yuan_back/,而是还在/login/,所以当刷新后
#     又得重新登录.

redirect函数

返回顶部

十六、Ajax

九、COOKIE 与 SESSION

1、创建后台管理员

?

1
python manage.py createsuperuser

十三、缓存

由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,5分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之前缓存的内容拿到,并返回。

Django中提供了6种缓存方式:

图片 55图片 56

开发调试
内存
文件
数据库
Memcache缓存(python-memcached模块)
Memcache缓存(pylibmc模块)

Django6种缓存方式

1、配置

a、开发调试

图片 57图片 58

    # 此为开始调试用,实际内部不做任何操作
    # 配置:
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.dummy.DummyCache',     # 引擎
                'TIMEOUT': 300,                                               # 缓存超时时间(默认300,None表示永不过期,0表示立即过期)
                'OPTIONS':{
                    'MAX_ENTRIES': 300,                                       # 最大缓存个数(默认300)
                    'CULL_FREQUENCY': 3,                                      # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
                },
                'KEY_PREFIX': '',                                             # 缓存key的前缀(默认空)
                'VERSION': 1,                                                 # 缓存key的版本(默认1)
                'KEY_FUNCTION' 函数名                                          # 生成key的函数(默认函数会生成为:【前缀:版本:key】)
            }
        }


    # 自定义key
    def default_key_func(key, key_prefix, version):
        """
        Default function to generate keys.

        Constructs the key used by all other methods. By default it prepends
        the `key_prefix'. KEY_FUNCTION can be used to specify an alternate
        function with custom key making behavior.
        """
        return '%s:%s:%s' % (key_prefix, version, key)

    def get_key_func(key_func):
        """
        Function to decide which key function to use.

        Defaults to ``default_key_func``.
        """
        if key_func is not None:
            if callable(key_func):
                return key_func
            else:
                return import_string(key_func)
        return default_key_func

View Code

b、内存

图片 59图片 60

    # 此缓存将内容保存至内存的变量中
    # 配置:
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
                'LOCATION': 'unique-snowflake',
            }
        }

    # 注:其他配置同开发调试版本

View Code

c、文件

图片 61图片 62

    # 此缓存将内容保存至文件
    # 配置:

        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
                'LOCATION': '/var/tmp/django_cache',
            }
        }
    # 注:其他配置同开发调试版本

View Code

d、数据库

图片 63图片 64

    # 此缓存将内容保存至数据库

    # 配置:
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
                'LOCATION': 'my_cache_table', # 数据库表
            }
        }

    # 注:执行创建表命令 python manage.py createcachetable

View Code

e、Memcache缓存(python-memcached模块)

图片 65图片 66

# 此缓存使用python-memcached模块连接memcache

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': '127.0.0.1:11211',
        }
    }

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': 'unix:/tmp/memcached.sock',
        }
    }   

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': [
                '172.19.26.240:11211',
                '172.19.26.242:11211',
            ]
        }
    }

View Code

f、Memcache缓存(pylibmc模块)

图片 67图片 68

    # 此缓存使用pylibmc模块连接memcache

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
            'LOCATION': '127.0.0.1:11211',
        }
    }

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
            'LOCATION': '/tmp/memcached.sock',
        }
    }   

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
            'LOCATION': [
                '172.19.26.240:11211',
                '172.19.26.242:11211',
            ]
        }
    }

View Code

2、应用

a. 全站使用

图片 69图片 70

   使用中间件,经过一系列的认证等操作,如果内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户,当返回给用户之前,判断缓存中是否已经存在,如果不存在则UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存

    MIDDLEWARE = [
        'django.middleware.cache.UpdateCacheMiddleware',
        # 其他中间件...
        'django.middleware.cache.FetchFromCacheMiddleware',
    ]

    CACHE_MIDDLEWARE_ALIAS = ""
    CACHE_MIDDLEWARE_SECONDS = ""
    CACHE_MIDDLEWARE_KEY_PREFIX = ""

View Code

b. 单独视图缓存

图片 71图片 72

    方式一:
        from django.views.decorators.cache import cache_page

        @cache_page(60 * 15)
        def my_view(request):
            ...

    方式二:
        from django.views.decorators.cache import cache_page

        urlpatterns = [
            url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)),
        ]

View Code

c、局部视图使用

图片 73图片 74

    a. 引入TemplateTag

        {% load cache %}

    b. 使用缓存

        {% cache 5000 缓存key %}
            缓存内容
        {% endcache %}

View Code

返回顶部

2、连表结构

  • 一对多:models.ForeignKey(其他表)
  • 多对多:models.ManyToManyField(其他表)
  • 一对一:models.OneToOneField(其他表)

图片 75图片 76

应用场景:

一对多:当一张表中创建一行数据时,有一个单选的下拉框(可以被重复选择)
例如:创建用户信息时候,需要选择一个用户类型【普通用户】【金牌用户】【铂金用户】等。
多对多:在某表中创建一行数据是,有一个可以多选的下拉框
例如:创建用户信息,需要为用户指定多个爱好
一对一:在某表中创建一行数据时,有一个单选的下拉框(下拉框中的内容被用过一次就消失了
例如:原有含10列数据的一张表保存相关信息,经过一段时间之后,10列无法满足需求,需要为原来的表再添加5列数据

应用场景:

图片 77图片 78

    ForeignKey(ForeignObject) # ForeignObject(RelatedField)
        to,                         # 要进行关联的表名
        to_field=None,              # 要关联的表中的字段名称
        on_delete=None,             # 当删除关联表中的数据时,当前表与其关联的行的行为
                                        - models.CASCADE,删除关联数据,与之关联也删除
                                        - models.DO_NOTHING,删除关联数据,引发错误IntegrityError
                                        - models.PROTECT,删除关联数据,引发错误ProtectedError
                                        - models.SET_NULL,删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
                                        - models.SET_DEFAULT,删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
                                        - models.SET,删除关联数据,
                                                      a. 与之关联的值设置为指定值,设置:models.SET(值)
                                                      b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)

                                                        def func():
                                                            return 10

                                                        class MyModel(models.Model):
                                                            user = models.ForeignKey(
                                                                to="User",
                                                                to_field="id"
                                                                on_delete=models.SET(func),)
        related_name=None,          # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
        related_query_name=None,    # 反向操作时,使用的连接前缀,用于替换【表名】     如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
        limit_choices_to=None,      # 在Admin或ModelForm中显示关联数据时,提供的条件:
                                    # 如:
                                            - limit_choices_to={'nid__gt': 5}
                                            - limit_choices_to=lambda : {'nid__gt': 5}

                                            from django.db.models import Q
                                            - limit_choices_to=Q(nid__gt=10)
                                            - limit_choices_to=Q(nid=8) | Q(nid__gt=10)
                                            - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
        db_constraint=True          # 是否在数据库中创建外键约束
        parent_link=False           # 在Admin中是否显示关联数据


    OneToOneField(ForeignKey)
        to,                         # 要进行关联的表名
        to_field=None               # 要关联的表中的字段名称
        on_delete=None,             # 当删除关联表中的数据时,当前表与其关联的行的行为

                                    ###### 对于一对一 ######
                                    # 1. 一对一其实就是 一对多   唯一索引
                                    # 2.当两个类之间有继承关系时,默认会创建一个一对一字段
                                    # 如下会在A表中额外增加一个c_ptr_id列且唯一:
                                            class C(models.Model):
                                                nid = models.AutoField(primary_key=True)
                                                part = models.CharField(max_length=12)

                                            class A(C):
                                                id = models.AutoField(primary_key=True)
                                                code = models.CharField(max_length=1)

    ManyToManyField(RelatedField)
        to,                         # 要进行关联的表名
        related_name=None,          # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
        related_query_name=None,    # 反向操作时,使用的连接前缀,用于替换【表名】     如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
        limit_choices_to=None,      # 在Admin或ModelForm中显示关联数据时,提供的条件:
                                    # 如:
                                            - limit_choices_to={'nid__gt': 5}
                                            - limit_choices_to=lambda : {'nid__gt': 5}

                                            from django.db.models import Q
                                            - limit_choices_to=Q(nid__gt=10)
                                            - limit_choices_to=Q(nid=8) | Q(nid__gt=10)
                                            - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
        symmetrical=None,           # 仅用于多对多自关联时,symmetrical用于指定内部是否创建反向操作的字段
                                    # 做如下操作时,不同的symmetrical会有不同的可选字段
                                        models.BB.objects.filter(...)

                                        # 可选字段有:code, id, m1
                                            class BB(models.Model):

                                            code = models.CharField(max_length=12)
                                            m1 = models.ManyToManyField('self',symmetrical=True)

                                        # 可选字段有: bb, code, id, m1
                                            class BB(models.Model):

                                            code = models.CharField(max_length=12)
                                            m1 = models.ManyToManyField('self',symmetrical=False)

        through=None,               # 自定义第三张表时,使用字段用于指定关系表
        through_fields=None,        # 自定义第三张表时,使用字段用于指定关系表中那些字段做多对多关系表
                                        from django.db import models

                                        class Person(models.Model):
                                            name = models.CharField(max_length=50)

                                        class Group(models.Model):
                                            name = models.CharField(max_length=128)
                                            members = models.ManyToManyField(
                                                Person,
                                                through='Membership',
                                                through_fields=('group', 'person'),
                                            )

                                        class Membership(models.Model):
                                            group = models.ForeignKey(Group, on_delete=models.CASCADE)
                                            person = models.ForeignKey(Person, on_delete=models.CASCADE)
                                            inviter = models.ForeignKey(
                                                Person,
                                                on_delete=models.CASCADE,
                                                related_name="membership_invites",
                                            )
                                            invite_reason = models.CharField(max_length=64)
        db_constraint=True,         # 是否在数据库中创建外键约束
        db_table=None,              # 默认创建第三张表时,数据库中表的名称

字段以及参数

一、wsgi接口

csrf_token标签

用于生成csrf_token的标签,用于防治跨站攻击验证。 其实,这里是会生成一个input标签,和其他表单标签一起提交给后台的。

六、Model&ORM

十二、分页

序列化

在django中,在将数据库中检索的数据返回给客户端用户,数据类型为QuerySet格式,而QuerySet格式不能被json格式化处理传到前端,因此在处理此类数据时有两种方法:

方法一:使用django自带的系列化模块 serializers模块

1、serializers

图片 79图片 80

from django.core import serializers

ret = models.BookType.objects.all()

data = serializers.serialize("json", ret)

使用serializers序列化

1、serializers序列化后的数据格式为列表,列表为每一个查询记录

图片 81

  2、serializers模块不能跨表查询,涉及一对多查询时,只能查询到关联字段

方法二:查询时转换为QuerySet字典或列表格式

2、json.dumps

图片 82图片 83

import json

#ret = models.BookType.objects.all().values('caption')
ret = models.BookType.objects.all().values_list('caption')

ret=list(ret)  #将QuerySet进行转化

result = json.dumps(ret)

json.dumps序列化

特殊的:

由于json.dumps时无法处理datetime日期,所以可以通过自定义处理器来做扩展,如:

图片 84图片 85

import json
from datetime import date
from datetime import datetime

class JsonCustomEncoder(json.JSONEncoder):

    def default(self, field):

        if isinstance(field, datetime):
            return o.strftime('%Y-%m-%d %H:%M:%S')
        elif isinstance(field, date):
            return o.strftime('%Y-%m-%d')
        else:
            return json.JSONEncoder.default(self, field)


ds = json.dumps(d, cls=JsonCustomEncoder)

datetime日期序列化

返回顶部

十一、Form与ModelForm

12.1分页器的使用

图片 86图片 87

复制代码

>>> from django.core.paginator import Paginator
>>> objects = ['john', 'paul', 'george', 'ringo']
>>> p = Paginator(objects, 2)

>>> p.count        #数据总数
4
>>> p.num_pages    #总页数
2
>>> type(p.page_range)  # `<type 'rangeiterator'>` in Python 2.
<class 'range_iterator'>
>>> p.page_range        #页码的列表
range(1, 3)     # =========[1,2]

>>> page1 = p.page(1)   #第1页的page对象
>>> page1
<Page 1 of 2>
>>> page1.object_list   #第1页的数据
['john', 'paul']

>>> page2 = p.page(2)
>>> page2.object_list    #第2页的数据
['george', 'ringo']
>>> page2.has_next()     #是否有下一页
False
>>> page2.has_previous() #是否有上一页
True
>>> page2.has_other_pages() #是否有其他页
True
>>> page2.next_page_number() #下一页的页码
Traceback (most recent call last):
...
EmptyPage: That page contains no results
>>> page2.previous_page_number()  #上一页的页码
1
>>> page2.start_index() # 本页第一条记录的序数(从1开始)
3
>>> page2.end_index() # 本页最后录一条记录的序数(从1开始)
4

>>> p.page(0)       #错误的页,抛出异常
Traceback (most recent call last):
...
EmptyPage: That page number is less than 1
>>> p.page(3)       #错误的页,抛出异常
Traceback (most recent call last):
...
EmptyPage: That page contains no results

复制代码

分页器参数及使用

10.1认证登录

?

1
from django.contrib import auth

django.contrib.auth中提供了许多方法,这里主要介绍其中的三个:

10.3.3  set_password(passwd)

图片 88图片 89

这个方法是用来更改密码的,使用步骤:
user=User.objects.get(username='')
user.set_password(passeord='')
user.save

更改密码

10.3.4  check_password(passwd)

?

1
用户需要修改密码的时候 首先要让他输入原来的密码 ,如果给定的字符串通过了密码检查,返回 True

10.3.5 修改密码

图片 90图片 91

使用 set_password() 来修改密码

user = User.objects.get(username='')
user.set_password(password='')
user.save 

使用 set_password() 来修改密码

十、Django的用户认证

四、Template模板

  python的模板:HTML代码+逻辑控制代码

4.2 标签(tag)的使用(使用大括号和百分比的组合来表示使用tag)

语法格式:    {% tags %}

优点:

  • AJAX使用Javascript技术向服务器发送异步请求;
  • AJAX无须刷新整个页面;
  • 因为服务器响应内容不再是整个页面,而是页面中的局部,所以AJAX性能高;

三、URL路由系统

3.2 有名分组(named group)

  上面的示例使用简单的、没有命名的正则表达式组(通过圆括号)来捕获URL 中的值并以位置 参数传递给视图。在更高级的用法中,可以使用命名的正则表达式组来捕获URL 中的值并以关键字 参数传递给视图。

  在Python 正则表达式中,命名正则表达式组的语法是(?P<name>pattern),其中name 是组的名称,pattern 是要匹配的模式。

下面是以上URLconf 使用命名组的重写:

图片 92图片 93

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
]

url有名分组

这个实现与前面的示例完全相同,只有一个细微的差别:捕获的值作为关键字参数而不是位置参数传递给视图函数。例如:

图片 94图片 95

/articles/2005/03/    
请求将调用views.month_archive(request, year='2005', month='03')函数
/articles/2003/03/03/ 
请求将调用函数views.article_detail(request, year='2003', month='03', day='03')。

url有名分组实例

在实际应用中,这意味你的URLconf 会更加明晰且不容易产生参数顺序问题的错误 —— 你可以在你的视图函数定义中重新安排参数的顺序。当然,这些好处是以简洁为代价;有些开发人员认为命名组语法丑陋而繁琐。

2、配置后台管理url

?

1
url(r'^admin/', include(admin.site.urls))

3、注册和配置django admin 后台管理页面

  a、在admin中执行如下配置

图片 96图片 97

from django.contrib import admin

from app01 import  models

admin.site.register(models.UserType)
admin.site.register(models.UserInfo)
admin.site.register(models.UserGroup)
admin.site.register(models.Asset)

配置admin,添加Model表

b、设置数据表名称

图片 98图片 99

class UserType(models.Model):
    name = models.CharField(max_length=50)

    class Meta:
        verbose_name = '用户类型'
        verbose_name_plural = '用户类型'

设置数据表名称

c、一些常用的设置技巧(在admin.py文件中配置)

图片 100图片 101

list_display:     指定要显示的字段
search_fields:  指定搜索的字段
list_filter:        指定列表过滤器
ordering:       指定排序字段

一些常用的设置技巧

d、打开表之后,设定默认显示,需要在model中作如下配置(在admin.py文件中配置)**

图片 102图片 103

class UserType(models.Model):
    name = models.CharField(max_length=50)

    def __unicode__(self):
        return self.name



from django.contrib import admin
from app01 import  models

class UserInfoAdmin(admin.ModelAdmin):
    list_display = ('username', 'password', 'email')


admin.site.register(models.UserType)
admin.site.register(models.UserInfo,UserInfoAdmin)
admin.site.register(models.UserGroup)
admin.site.register(models.Asset)

设定默认显示

e、为数据表添加搜索功能(在admin.py文件中配置)**

图片 104图片 105

from django.contrib import admin

from app01 import  models

class UserInfoAdmin(admin.ModelAdmin):
    list_display = ('username', 'password', 'email')
    search_fields = ('username', 'email')

admin.site.register(models.UserType)
admin.site.register(models.UserInfo,UserInfoAdmin)
admin.site.register(models.UserGroup)
admin.site.register(models.Asset)

为数据表添加搜索功能

f、添加快速过滤(在admin.py文件中配置)**

图片 106图片 107

from django.contrib import admin

from app01 import  models

class UserInfoAdmin(admin.ModelAdmin):
    list_display = ('username', 'password', 'email')
    search_fields = ('username', 'email')
    list_filter = ('username', 'email')



admin.site.register(models.UserType)
admin.site.register(models.UserInfo,UserInfoAdmin)
admin.site.register(models.UserGroup)
admin.site.register(models.Asset)

添加快速过滤

返回顶部

11.2.2 通过ModelForm完成三张表格的数据新增:

1)  在app01目录下建立forms.py文件,今后将所有的form都写在这个文件中,这个文件需要在views.py中导入,方便导入相应的FORM

2)  创建ModelForm:

forms.py:

图片 108图片 109

# -*- coding: UTF-8 -*-  
from django.forms import ModelForm  
from .models import Node,Line,Device  

#定义Node的Form,Form名字为 模式名 Form  
class NodeForm(ModelForm):  
    #自定义ModelForm的内容  
    class Meta:  
        #该ModelForm参照Model: Node  
        model = Node  
        #在Form中不显示node_signer这个字段  
        exclude = ['node_signer']  

class LineForm(ModelForm):  
    class Meta:  
        model = Line  
        exclude = ['line_signer']  

class DeviceForm(ModelForm):  
    class Meta:  
        model = Device  
        exclude = ['device_signer']  

forms.py

 建立url与view的关联关系

?

1
url(r'^add/', echo.views.add), 

在views.py中建立相应的函数

views.py:

图片 110图片 111

# -*- coding: UTF-8 -*-  
from .models import Node,Line,Device  
from forms import NodeForm,LineForm,DeviceForm  
from django.shortcuts import render, redirect  
def add(request):  
    #获取来自NodeForm的表单数据  
    form = NodeForm(request.POST or None)  
    #判断form是否有效  
    if form.is_valid():  
        #创建实例,需要做些数据处理,暂不做保存  
        instance = form.save(commit=False)  
        #将登录用户作为登记人  
        instance.node_signer = request.user  
        #保存该实例  
        instance.save()  
        #跳转至列表页面  
        return redirect('/lists/')  

    #创建context来集中处理需要传递到页面的数据  
    context = {  
        'form': form,  
    }  
    #如果没有有效提交,则仍留在原来页面  
    return render(request, 'add.html',  context)  

views.py

在templates文件夹下建立HTML文件,add.html

add.html:

图片 112图片 113

<!DOCTYPE html>  
<html>  
<head lang="en">  
    <meta charset="UTF-8">  
    <title></title>  
</head>  
<body>  
 <form method='POST' action=''>{% csrf_token %}  
        {{ form }}  
        <input type='submit' value='提交' />  
 </form>  

</body>  
</html>  

add.html

返回顶部

5.1.1. 基本使用

使用方法为:urls.py 修改为如下:

图片 114图片 115

from mytest import views

urlpatterns = [
    # url(r‘^index/‘, views.index),
    url(r‘^index/‘, views.Index.as_view()),
]
#注:url(r‘^index/‘, views.Index.as_view()),  是固定用法。

CBV中urls.py文件

views.py 修改为如下:

图片 116图片 117

from django.views import View

class Index(View):

    def dispatch(self, request, *args, **kwargs):
        res = super(AuthView,self).dispatch(request, *args, **kwargs)
        return res

    def get(self, req):
        print(‘method is :‘   req.method)
        return render(req, ‘index.html‘)

    def post(self, req):
        print(‘method is :‘   req.method)
        return render(req, ‘index.html‘)
#注:1、类要继承 View ,类中函数名必须小写。
        2、类中首先执行的是  dispatch方法

CBV中views.py文件

六、Model&ORM

4.1.3 变量的过滤器(filter)的使用

图片 118图片 119

#语法格式:      {{obj|filter:param}}

# 1  add          :   给变量加上相应的值
# 2  addslashes   :    给变量中的引号前加上斜线
# 3  capfirst     :    首字母大写
# 4  cut          :   从字符串中移除指定的字符
# 5  date         :   格式化日期字符串
# 6  default      :   如果值是False,就替换成设置的默认值,否则就是用本来的值
# 7  default_if_none:  如果值是None,就替换成设置的默认值,否则就使用本来的值


#实例:

#value1="aBcDe"
{{ value1|upper }}<br>

#value2=5
{{ value2|add:3 }}<br>

#value3='he  llo wo r ld'
{{ value3|cut:' ' }}<br>

#import datetime
#value4=datetime.datetime.now()
{{ value4|date:'Y-m-d' }}<br>

#value5=[]
{{ value5|default:'空的' }}<br>

#value6='<a href="#">跳转</a>'

{{ value6 }}

{% autoescape off %}
  {{ value6 }}
{% endautoescape %}

{{ value6|safe }}<br>

{{ value6|striptags }}

#value7='1234'
{{ value7|filesizeformat }}<br>
{{ value7|first }}<br>
{{ value7|length }}<br>
{{ value7|slice:":-1" }}<br>

#value8='http://www.baidu.com/?a=1&b=3'
{{ value8|urlencode }}<br>
    value9='hello I am yuan'

filter过滤器使用说明

3.5 指定视图参数的默认值

有一个方便的小技巧是指定视图参数的默认值。 下面是一个URLconf 和视图的示例

图片 120图片 121

# URLconf
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^blog/$', views.page),
    url(r'^blog/page(?P<num>[0-9] )/$', views.page),
]

# View (in blog/views.py)
def page(request, num="1"):

    ...

View Code

 

  在上面的例子中,两个URL模式指向同一个视图views.page —— 但是第一个模式不会从URL 中捕获任何值。如果第一个模式匹配,page() 函数将使用num参数的默认值"1"。如果第二个模式匹配,page() 将使用正则表达式捕获的num 值。

8.2.2 POST请求

图片 122图片 123

(1). 数据不会出现在地址栏中
(2). 数据的大小没有上限
(3). 有请求体
(4). 请求体中如果存在中文,会使用URL编码!

POST请求特点

图片 124图片 125

我们都知道Http协议中参数的传输是"key=value"这种简直对形式的,如果要传多个参数就需要用“&”符号对键值对进行分割。如"?name1=value1&name2=value2",这样在服务端在收到这种字符串的时候,会用“&”分割出每一个参数,然后再用“=”来分割出参数值。



针对“name1=value1&name2=value2”我们来说一下客户端到服务端的概念上解析过程: 
  上述字符串在计算机中用ASCII吗表示为: 
  6E616D6531 3D 76616C756531 26 6E616D6532 3D 76616C756532。 
   6E616D6531:name1 
   3D:= 
   76616C756531:value1 
   26:&
   6E616D6532:name2 
   3D:= 
   76616C756532:value2 
   服务端在接收到该数据后就可以遍历该字节流,首先一个字节一个字节的吃,当吃到3D这字节后,服务端就知道前面吃得字节表示一个key,再想后吃,如果遇到26,说明从刚才吃的3D到26子节之间的是上一个key的value,以此类推就可以解析出客户端传过来的参数。

   现在有这样一个问题,如果我的参数值中就包含=或&这种特殊字符的时候该怎么办。 
比如说“name1=value1”,其中value1的值是“va&lu=e1”字符串,那么实际在传输过程中就会变成这样“name1=va&lu=e1”。我们的本意是就只有一个键值对,但是服务端会解析成两个键值对,这样就产生了奇异。

如何解决上述问题带来的歧义呢?解决的办法就是对参数进行URL编码 
   URL编码只是简单的在特殊字符的各个字节前加上%,例如,我们对上述会产生奇异的字符进行URL编码后结果:“name1=va&lu=”,这样服务端会把紧跟在“%”后的字节当成普通的字节,就是不会把它当成各个参数或键值对的分隔符。

为什么要进行URL编码

注意

8.1 HTTP**概述**

HTTP(hypertext transport protocol),即超文本传输协议。这个协议详细规定了浏览器和万维网服务器之间互相通信的规则。

HTTP就是一个通信规则,通信规则规定了客户端发送给服务器的内容格式,也规定了服务器发送给客户端的内容格式。其实我们要学习的就是这个两个格式!客户端发送给服务器的格式叫“请求协议”;服务器发送给客户端的格式叫“响应协议”。

特点:

  • HTTP叫超文本传输协议,基于请求/响应模式的!
  • HTTP是无状态协议。

URL:统一资源定位符,就是一个网址:协议名://域名:端口/路径,例如:http://www.oldboy.cn:80/index.html

中间件之process_exception

process_exception(self, request, exception)

当views的函数中出现错误时,就会执行process_exception方法

如果在中间中添加了process_exception方法,工作图示为:

图片 126

  这样当用户发起请求的时候到达中间件3的process_request之后会到达urls路由关系映射这里,如果匹配到了就会到中间件1的process_view,然后依次传递到中间件3的process_view,到达view函数。如果view函数中有报错,则会从中间件3依次向上判断每个中间件的process_exception是否能匹配到这个错误信息,如果匹配到则直接返回到最后一个中间件,这里即中间件3的process_response,然后依次返回到用户,如果没有匹配到这个错误则直接在页面显示错误信息。如果view函数中没有错误,则到中间3即最后一个中间件3的process_response,然后依次向上,传到用户

index.html

图片 127图片 128

{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <link rel="stylesheet" href="{% static 'bootstrap.css' %}">

</head>
<body>

<div class="container">

    <h4>分页器</h4>
    <ul>

    {% for book in book_list %}
         <li>{{ book.title }} {{ book.price }}</li>
    {% endfor %}

</ul>

    <ul class="pagination" id="pager">

                 {% if book_list.has_previous %}
                    <li class="previous"><a href="/blog/?page={{ book_list.previous_page_number }}">上一页</a></li>
                 {% else %}
                    <li class="previous disabled"><a href="#">上一页</a></li>
                 {% endif %}


                 {% for num in paginator.page_range %}

                     {% if num == currentPage %}
                       <li class="item active"><a href="/blog/?page={{ num }}">{{ num }}</a></li>
                     {% else %}
                       <li class="item"><a href="/blog/?page={{ num }}">{{ num }}</a></li>

                     {% endif %}
                 {% endfor %}


                 {% if book_list.has_next %}
                    <li class="next"><a href="/blog/?page={{ book_list.next_page_number }}">下一页</a></li>
                 {% else %}
                    <li class="next disabled"><a href="#">下一页</a></li>
                 {% endif %}

            </ul>
</div>

</body>
</html>

index.html

0、Django的生命周期

图片 129

 

$.ajax参数

图片 130图片 131

######################------------data---------################

       data: 当前ajax请求要携带的数据,是一个json的object对象,ajax方法就会默认地把它编码成某种格式
             (urlencoded:?a=1&b=2)发送给服务端;此外,ajax默认以get方式发送请求。

             function testData() {
               $.ajax("/test",{     //此时的data是一个json形式的对象
                  data:{
                    a:1,
                    b:2
                  }
               });                   //?a=1&b=2
######################------------processData---------################

processData:声明当前的data数据是否进行转码或预处理,默认为true,即预处理;if为false,
             那么对data:{a:1,b:2}会调用json对象的toString()方法,即{a:1,b:2}.toString()
             ,最后得到一个[object,Object]形式的结果。

######################------------contentType---------################

contentType:默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。
             用来指明当前请求的数据编码格式;urlencoded:?a=1&b=2;如果想以其他方式提交数据,
             比如contentType:"application/json",即向服务器发送一个json字符串:
               $.ajax("/ajax_get",{

                  data:JSON.stringify({
                       a:22,
                       b:33
                   }),
                   contentType:"application/json",
                   type:"POST",

               });                          //{a: 22, b: 33}

             注意:contentType:"application/json"一旦设定,data必须是json字符串,不能是json对象


######################------------traditional---------################

traditional:一般是我们的data数据有数组时会用到 :data:{a:22,b:33,c:["x","y"]},
              traditional为false会对数据进行深层次迭代;

$.ajax参数

步骤:

a、新建 base.html,放在template目录下

b、使用模板标签: {% block %}分块,用于子模板继承 

图片 132图片 133

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <h1>My helpful timestamp site</h1>
    {% block content %}{% endblock %}
    {% block footer %}
    <hr>
    <p>Thanks for visiting my site.</p>
    {% endblock %}
</body>
</html>

新建母版文件(base.html)

c、子模版集成(即重载block块)

图片 134图片 135

{% extends "base.html" %}

{% block title %}The current time{% endblock %}

{% block content %}
<p>It is now {{ current_date }}.</p>
{% endblock %}

子母版继承

继承的常见三层法:

图片 136图片 137

   <1> 创建 base.html 模板,在其中定义站点的主要外观感受。 这些都是不常修改甚至从不修改的部分。
   <2> 为网站的每个区域创建 base_SECTION.html 模板(例如, base_photos.html 和 base_forum.html )。这些模板对base.html 进行拓展,
       并包含区域特定的风格与设计。
   <3> 为每种类型的页面创建独立的模板,例如论坛页面或者图片库。 这些模板拓展相应的区域模板。

继承的常见三层法

模板继承的一些诀窍

图片 138图片 139

<1>如果在模板中使用 {% extends %} ,必须保证其为模板中的第一个模板标记。 否则,模板继承将不起作用。

 <2>一般来说,基础模板中的 {% block %} 标签越多越好。 记住,子模板不必定义父模板中所有的代码块,因此
    你可以用合理的缺省值对一些代码块进行填充,然后只对子模板所需的代码块进行(重)定义。 俗话说,钩子越
    多越好。

 <3>如果发觉自己在多个模板之间拷贝代码,你应该考虑将该代码段放置到父模板的某个 {% block %} 中。
    如果你需要访问父模板中的块的内容,使用 {{ block.super }}这个标签吧,这一个魔法变量将会表现出父模
    板中的内容。 如果只想在上级代码块基础上添加内容,而不是全部重载,该变量就显得非常有用了。

 <4>不允许在同一个模板中定义多个同名的 {% block %} 。 存在这样的限制是因为block 标签的工作方式是双向的。
    也就是说,block 标签不仅挖了一个要填的坑,也定义了在父模板中这个坑所填充的内容。如果模板中出现了两个
    相同名称的 {% block %} 标签,父模板将无从得知要使用哪个块的内容。

模板继承的诀窍

 返回顶部

10.1.2  login(HttpRequest, user)  

图片 140图片 141

该函数接受一个HttpRequest对象,以及一个认证了的User对象

此函数使用django的session框架给某个已认证的用户附加上session id等信息。

from django.contrib.auth import authenticate, login

def my_view(request):
  username = request.POST['username']
  password = request.POST['password']
  user = authenticate(username=username, password=password)
  if user is not None:
    login(request, user)
    # Redirect to a success page.
    ...
  else:
    # Return an 'invalid login' error message.
    ...

login

本文由美洲杯在哪买球发布于计算机教程,转载请注明出处:Django Ajax jQuery实现网页动态更新的实例

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。