day_19_chouti

一、上节回顾

1. 分页
- Django内置
- 自定义分页
2. Form验证
- 对用户请求数据验证(Ajax,Form)
Ajax -> Form验证(上次提交内容保留)(验证)
Form表单 -> Form验证(验证,保留上次内容)

- 类
    class Foo(forms.Form):
        xx1 = xx(定制插件)
        xx2 = xx()
        xx3 = xx()
- 使用:
    obj = Foo()  -> 用于生成HTML(内容为空)
    obj = Foo(request.POST)
    if obj.is_valid():
        obj.cleaned_data
        # models.XX.objects.create(**obj.cleaned_data)
    else:
        obj.errors['xx1'][0]

3. 中间件 # 在请求者和服务器之间的一系列规则

4. Models补充
单表操作:
多表操作:

selete_related()        # 跨表操作,当数据量很大时,查询速度会很慢

    user_list = Models.UserInfo.objects.all()
    for row in user_list: 10
        print(row.username,row.email,row.part_id,row.part.title)
    ==> 11次跨表操作

    user_list = Models.UserInfo.objects.all().selete_realated('part','usertype') # FK字段名称
    for row in user_list: 10
        print(row.username,row.email,row.part_id,row.part.title)
    ==> 1次跨表操作

prefetch_realated()     # 不跨表操作,连表变单表
    user_list = Models.UserInfo.objects.filter(id=1).prefetch_realated('part','usertype',"group__xxx")      # FK字段名称
    # 第一句:Models.UserInfo.objects.all()[0:10]
    # part_id = [1,]    # 把相关的部门信息,给拿回来
    # 第二句:Models.Part.objects.filter(id__in=part_id)
    # usertype_id = [2,]
    # 第三句:Models.UserType.objects.filter(id__in=usertype_id)
    for row in user_list: 10
        print(row.username,row.email,row.part_id,row.part.title)
    ==> 2次单表操作
View Code

二、models补充

性能相关:
    selete_realated
    prefetch_realated
其他:
    models.UserInfo.objects.all()
    u = models.UserInfo.objects.all().only('id','name') # 指定相应的列,不要.only之外的属性,那样效率会很低
    u = models.UserInfo.objects.all().defer('name')     # 就name不取

    # 自带指定相应的列
    models.UserInfo.objects.values('id')
    models.UserInfo.objects.values_list('id')

三、缓存 # 耦合非常低,解耦
6中方式的缓存
配置:
文件: 路径
内存: 变量名称 全局变量
数据库: 表名
memcache缓存: IP端口

# settings.py

# from django.core.cache.backends.dummy import DummyCache
CACHES = {
    'default': {
        # 'BACKEND': 'django.core.cache.backends.dummy.DummyCache',  # 引擎
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',  # 内存
        'LOCATION': 'unique-snowflake',
        # 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',     # 文件
        # 'LOCATION': '/var/tmp/django_cache',
        'TIMEOUT': 300,  # 缓存超时时间(默认300,None表示永不过期,0表示立即过期)
        'OPTIONS': {
            'MAX_ENTRIES': 300,  # 最大缓存个数(默认300)
            'CULL_FREQUENCY': 10,  # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
        },
        # 'KEY_PREFIX': 'prev',  # 缓存key的前缀(默认空)
        # 'VERSION': 1,  # 缓存key的版本(默认1)
        # 'KEY_FUNCTION' 函数名  # 生成key的函数(默认函数会生成为:【前缀:版本:key】)
    }
}

使用:
a. 全站缓存
请求时,缓存放在中间件的后端;返回时,在1处使用
全站缓存图示一:

全站缓存图示二:

 

 # settings.py

from django.middleware.cache import FetchFromCacheMiddleware
MIDDLEWARE = [
    'django.middleware.cache.UpdateCacheMiddleware',
            # 原来这些中间件
    'django.middleware.cache.FetchFromCacheMiddleware',
]

b. 单独视图函数 , 既是使用cache_page进行对视图函数进行装饰
# views.py

from django.views.decorators.cache import cache_page
@cache_page(10)
def index(request):
    ctime = time.time()
    return render(request,'index.html',{'ctime': ctime})
# 缓存
def home(request):
    ctime = time.time()
    return render(request, 'index.html', {'ctime': ctime})
View Code

c. 局部模板
# index.html

{% load cache %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
        {% cache 5000 xxxxx %}
            <h1>{{ ctime }}</h1>
        {% endcache %}

    <h3>{{ ctime }}</h3>
</body>
</html>

**自定义:利用中间件/装饰器/simple_tag/自定义操作**

四、模板渲染知识补充
render在进行渲染时,会把变量替换成值,找不到变量就不执行
# views.py

def test(request):
    from s16day19 import pizza_done
    pizza_done.send(sender='xxxxx', toppings=123, size=456)

# test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>{{ n1 }}</h1>
    <h1>{{ n2 }}</h1>

    <script>
        alert("{{ n2 }}");  //带引号的才是字符串,数字不需要加引号
    </script>

</body>
</html>
View Code

五、信号
Django程序起来时,信号才加载。

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          # 创建数据库连接时,自动触发
     
    
# 内置信号(自动触发)
def fffffff(sender, **kwargs):  # sender表示谁触发的
    print("信号被触发",sender,kwargs)
def fffffff1(sender, **kwargs):
    print("信号被触发",sender,kwargs)
    
pre_delete.connect(fffffff)
pre_delete.connect(fffffff1)

# __init__.py

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

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

# 内置信号
def fffffff(sender, **kwargs):
    print("信号被触发",sender,kwargs)
pre_delete.connect(fffffff)

def callback(sender, **kwargs):
    print("邮箱发消息")
    print(sender, kwargs)

pizza_done.connect(callback)
# pizza_done.connect(callback1)
View Code

# views.py

def test(request):
    from s16day19 import pizza_done
    pizza_done.send(sender='xxxxx', toppings=123, size=456)

    return render(request,'test.html',{'n1': 123,'n2': "root"})

六、Ajax与序列化
创建数据库表
普通请求 -> render渲染
Ajax -> render生成局部HTML ***局部数据:应用单一
Ajax -> HttpResponse('数据') ***接口:为别人提供数据(Ajax自己生成)***

普通请求 -> render渲染

# models.py
class UserInfo(models.Model):
    username = models.CharField(max_length=32)
    pwd = models.CharField(max_length=32)
# views.py
def index(request):
    # models.UserInfo.objects.create(username='u1',pwd='123123')
    # models.UserInfo.objects.create(username='u2',pwd='123123')
    user_list = models.UserInfo.objects.all()
    return render(request,'index.html',{'user_list': user_list})
View Code

# index.html

{% load cache %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <ul>
        {% for row in user_list %}
        <li>{{ row.username }}</li>
        {% endfor %}
    </ul>
</body>
</html>
View Code

Ajax -> render生成局部HTML ***局部数据:应用单一
# views.py

def show(request):
    return render(request, 'show.html')

def get_data(request):
    user_list = models.UserInfo.objects.all()
    # 1. 找模板渲染之后,生成字符串
    return render(request,'tpl.html',{'user_list': user_list})
View Code

# show.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <div>评论</div>
    <div id="content">
        <ul>
        </ul>
    </div>
</body>
<script src="/static/jquery.js"></script>
<script>
    $(function () {
        $.ajax({
            url: '/get-data/',
            type: 'GET',
            success:function (data) {
                data = JSON.parse(data)
                $.each(data,function (i,row) {
                    var tag = document.createElement('li');
                    tag.innerHTML = row.name;
                    $('#content ul').append(tag);
                })
            }
        })
    })
</script>
</html>
View Code

# tpl.html

<ul>
    {% for row in user_list %}
    <li>{{ row.username }}</li>
    {% endfor %}
</ul>

Ajax -> HttpResponse('数据') ***接口:为别人提供数据(Ajax自己生成)***
下面就是对这种的描述

1. render和HttpResponse的关系?
render返回:
a. 模板+数据进行替换
b. HttpResponse(数据)
HttpResponse:
a. HttpResponse(数据)
2. Ajax请求时,响应内容只能用HttpResponse吗?
HttpResponse和render都可以

Models获取数据时,获取数据的三种方式

# views.py
user_list = models.UserInfo.objects.all()
user_list = list(user_list)

# Models获取数据时,序列化方式一
from django.core import serializers
user_list = models.UserInfo.objects.all()
data = serializers.serialize("json", user_list)
return HttpResponse(data)

# Models获取数据时,序列化方式二 *****************推荐使用
user_list = models.UserInfo.objects.values('id','username')
user_list = list(user_list)
import json
return HttpResponse(json.dumps(user_list))

# Models获取数据时,序列化方式三
user_list = models.UserInfo.objects.values_list('id', 'username')
user_list = list(user_list)
import json
return HttpResponse(json.dumps(user_list))
View Code

Django中Ajax方式获取ORM获取数据数据时,涉及序列化操作
# views.py

import json
ret = {'status': False,'data': None, 'error': None}
try:
    user_list = models.UserInfo.objects.values('id','urname')
    user_list = list(user_list)
    ret['status'] = True
    ret['data'] = user_list
except Exception as e:
    ret['error'] = "获取数据失败"
data = json.dumps(ret)
return HttpResponse(data)
View Code

# utils.py 使用class方式进行规范化统一输出

class BaseReponse:
    def __init__(self):
        self.status = False
        self.data = None
        self.error = None

# views.py 进行数据的异常处理

from app01 import models
from utils import BaseReponse

import json
ret = BaseReponse()
try:
    user_list = models.UserInfo.objects.values('id','urname')
    user_list = list(user_list)
    ret.status = True
    ret.data = user_list
except Exception as e:
    ret.error = "获取数据失败"
data = json.dumps(ret.__dict__)
return HttpResponse(data)
View Code

# show.html

{% load cache %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <div>评论</div>
    <div id="content">
        <ul>
        </ul>
    </div>
    <script src="/static/jquery.js"></script>
    <script>
        $(function () {

            $.ajax({
                url: '/get-data/',
                type: 'GET',
                success:function (data) {
                    data = JSON.parse(data);
                    if (data.status){
                        console.log(data.data);
                        $.each(data.data,function (index,row) {
                            var tag = document.createElement('li');
                            tag.innerHTML = row.username;
                            $('#content ul').append(tag);
                        })
                    }else{
                        alert(data.error);
                    }
                }
            })
        })
    </script>
</body>
</html>
View Code

 

抽屉页面分析

一、Ajax操作

- bootstrap对话框实现

- Ajax操作
a. 发送数据,Form验证显示全部错误信息
PS: 主机管理时,添加和编辑
# settings.py中关闭csrftoken

# models.py

class UserInfo(models.Model):
    username = models.CharField(max_length=32)
    pwd = models.CharField(max_length=32)

class News(models.Model):
    title = models.CharField(max_length=64)
    img = models.CharField(max_length=128)

# urls.py # 配置路由系统

from app01 import views
url(r'^index/', views.index),
url(r'^login/', views.login),
url(r'^logout/', views.logout),

# views.py # 编写路由函数的规则

import json
from django.shortcuts import render,HttpResponse
from app01 import models
from utils import BaseReponse
from app01 import forms

def index(request):
    news_list = models.News.objects.all()
    return render(request,'index.html',{'news_list': news_list})

def login(request):
    response = BaseReponse()
    try:
        obj = forms.LoginForm(request.POST)
        if obj.is_valid():
            # models.UserInfo.objects.filter(username=obj.cleaned_data['username'],pwd=obj.cleaned_data['pwd'])
            v = models.UserInfo.objects.filter(**obj.cleaned_data).count()
            if v:
                response.status = True
            else:
                response.status = False
                response.error = "用户名或密码错误"
        else:
            print(obj.errors)
            response.status = False
            response.error = "asdasdf"
            response.error = obj.errors
    except Exception as e:
        response.status = False
        response.error = '请求失败'
    return HttpResponse(json.dumps(response.__dict__, ensure_ascii=False))  # 遇到中文,不更改
def logout(request):
    request.session.clear()
    return redirect('/index/')
View Code

# forms.py # form表单验证

from django.forms import Form
from django.forms import fields

class LoginForm(Form):
    username = fields.CharField(min_length=6,max_length=18)
    pwd = fields.CharField(min_length=12)

# utils.py # 定制回复信息

class BaseReponse:
    def __init__(self):
        self.status = False
        self.data = None
        self.error = None

# index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        .shadow{
            position: fixed;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
            background-color: #0f0f0f;
            opacity: 0.5;
            z-index: 999;
        }
        .modal{
            position: fixed;
            z-index: 1000;
            top: 50%;
            left: 50%;
            width: 400px;
            height: 300px;
            margin-left: -200px;
            margin-top: -150px;
            background-color: white;
            padding: 20px;
        }
        .hide{
            display: none;
        }
    </style>
</head>
<body>
    <h2>新闻列表</h2>
    <div>
        {% for row in news_list %}
            <div>{{ row.title }}</div>
        {% endfor %}
    </div>
    <a id="btn">登录</a>

    <div id="sd" class="shadow hide"></div>
    <div id="md" class="modal hide">
        <p><input type="text" id="username" name="username" placeholder="用户名" /></p>
        <p><input type="password" id="pwd" name="pwd"  placeholder="密码"/></p>

        <a id="sbm">提交</a>
        <a id="cancle">取消</a>
    </div>
    <script src="/static/jquery.js"></script>
    <script>
        $(function () {
            $('#btn').click(function () {
                $('#sd,#md').removeClass('hide');
            });
            $('#cancle').click(function () {
                $('#sd,#md').addClass('hide');
            });
            $('#sbm').click(function () {
                $.ajax({
                    url: '/login/',
                    type: 'POST',
                    data: {'username': $('#username').val(),'pwd': $('#pwd').val()},
                    dataType: 'JSON',
                    success:function (arg) {
                        if(arg.status){

                        }else{
                            $.each(arg.error,function (k,v) {
                                // k = username,v = [xxxx,]
                                var tag = document.createElement('span');
                                tag.innerHTML = v[0];
                                $('#' + k).after(tag);
                            })
                        }
                    }
                })
            })
        })
    </script>
</body>
</html>
View Code

b. 登录状态显示 # 给所有的显示页面制作一个公共的模板

{% if request.session.uuu %}
    <a>{{ request.session.uuu }}</a>
{% else %}
    <a id="btn">登录</a>
{% endif %}

# views.py # 路由系统设置

from app01 import views
url(r'^index/', views.index),
url(r'^login/', views.login),
url(r'^home/', views.home),

# forms.py和utils.py同上

# views.py # 视图函数编写
v = models.UserInfo.objects.filter(**obj.cleaned_data).first() 

import json
from django.shortcuts import render,HttpResponse
from app01 import models
from utils import BaseReponse
from app01 import forms

def index(request):
    news_list = models.News.objects.all()
    return render(request,'index.html',{'news_list': news_list})

def login(request):
    response = BaseReponse()
    try:
        obj = forms.LoginForm(request.POST)
        if obj.is_valid():
            # models.UserInfo.objects.filter(username=obj.cleaned_data['username'],pwd=obj.cleaned_data['pwd'])
            v = models.UserInfo.objects.filter(**obj.cleaned_data).first()   # 验证用户名和密码登陆是否成功
            if v:
                request.session['uuu'] = v.username
                response.status = True
            else:
                response.status = False
                response.error = "用户名或密码错误"
        else:
            print(obj.errors)
            response.status = False
            # response.error = "asdasdf"
            response.error = obj.errors
    except Exception as e:
        response.status = False
        response.error = '请求失败'
    return HttpResponse(json.dumps(response.__dict__, ensure_ascii=False))

def home(request):
    return render(request, 'home.html')
View Code

#layout.html   # 编写模板函数的模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        .shadow{
            position: fixed;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
            background-color: #0f0f0f;
            opacity: 0.5;
            z-index: 999;
        }
        .modal{
            position: fixed;
            z-index: 1000;
            top: 50%;
            left: 50%;
            width: 400px;
            height: 300px;
            margin-left: -200px;
            margin-top: -150px;
            background-color: white;
            padding: 20px;
        }
        .hide{
            display: none;
        }
    </style>
</head>
<body>
    {% if request.session.uuu %}
        <a>{{ request.session.uuu }}</a>
    {% else %}
        <a id="btn">登录</a>
    {% endif %}
    {% block content %} {% endblock %}
    <div id="sd" class="shadow hide"></div>
    <div id="md" class="modal hide">
        <p><input type="text" id="username" name="username" placeholder="用户名" /></p>
        <p><input type="password" id="pwd" name="pwd"  placeholder="密码"/></p>
        <a id="sbm">提交</a>
        <a id="cancle">取消</a>
    </div>
    <script src="/static/jquery.js"></script>
    <script>
        $(function () {
            $('#btn').click(function () {
                $('#sd,#md').removeClass('hide');
            });
            $('#cancle').click(function () {
                $('#sd,#md').addClass('hide');
            });
            $('#sbm').click(function () {
                $.ajax({
                    url: '/login/',
                    type: 'POST',
                    data: {'username': $('#username').val(),'pwd': $('#pwd').val()},
                    dataType: 'JSON',
                    success:function (arg) {
                        if(arg.status){
                            location.reload();
                        }else{
                            $.each(arg.error,function (k,v) {
                                // k = username,v = [xxxx,]
                                var tag = document.createElement('span');
                                tag.innerHTML = v[0];
                                $('#' + k).after(tag);
                            })
                        }
                    }
                })

            })
        })
    </script>
</body>
</html>
View Code

# index.html

{% extends "layout.html" %}

{% block content %}
    <h1>新闻列表</h1>
    {% for row in news_list %}
        <div>{{ row.title }}</div>
    {% endfor %}

{% endblock %}

# home.html

{% extends "layout.html" %}

{% block content %}
    <h1>Home</h1>
{% endblock %}

c. Ajax ---> CSRF
1. 手动找到并携带
{% csrf_token %}
data: {'username': $('#username').val(),'pwd': $('#pwd').val(),"csrfmiddlewaretoken":$('input[name="csrfmiddlewaretoken"]').val()},

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        .shadow{
            position: fixed;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
            background-color: #0f0f0f;
            opacity: 0.5;
            z-index: 999;
        }
        .modal{
            position: fixed;
            z-index: 1000;
            top: 50%;
            left: 50%;
            width: 400px;
            height: 300px;
            margin-left: -200px;
            margin-top: -150px;
            background-color: white;
            padding: 20px;
        }
        .hide{
            display: none;
        }
    </style>
</head>
<body>
    {% if request.session.uuu %}
        <a>{{ request.session.uuu }}</a>
    {% else %}
        <a id="btn">登录</a>
    {% endif %}
    {% block content %} {% endblock %}
    <div id="sd" class="shadow hide"></div>
    <div id="md" class="modal hide">
        {% csrf_token %}
        <p><input type="text" id="username" name="username" placeholder="用户名" /></p>
        <p><input type="password" id="pwd" name="pwd"  placeholder="密码"/></p>
        <a id="sbm">提交</a>
        <a id="cancle">取消</a>
    </div>
    <script src="/static/jquery.js"></script>
    <script>
        $(function () {
            $('#btn').click(function () {
                $('#sd,#md').removeClass('hide');
            });
            $('#cancle').click(function () {
                $('#sd,#md').addClass('hide');
            });
            $('#sbm').click(function () {
                $.ajax({
                    url: '/login/',
                    type: 'POST',
                    data: {'username': $('#username').val(),'pwd': $('#pwd').val(),"csrfmiddlewaretoken":$('input[name="csrfmiddlewaretoken"]').val()},
                    dataType: 'JSON',
                    success:function (arg) {
                        if(arg.status){
                            location.reload();
                        }else{
                            $.each(arg.error,function (k,v) {
                                // k = username,v = [xxxx,]
                                var tag = document.createElement('span');
                                tag.innerHTML = v[0];
                                $('#' + k).after(tag);
                            })
                        }
                    }
                })

            })
        })
    </script>
</body>
</html>
View Code

2. - HTML中创建Form表单将标签包含在内

<form id="f11">
    {% csrf_token %}
    <p><input type="text" id="username" name="username" placeholder="用户名" /></p>
    <p><input type="password" id="pwd" name="pwd"  placeholder="密码"/></p>
</form>
- data: $('#f11').serialize(), 

3. - cookie中获取csrftoken的值 # 需要安装jquery的插件
- 将值携带到请求头中  

<script src="/static/jquery.cookie.js"></script> 
$.ajax({
    header: {"X-CSRFToken": $.cookie('csrftoken')},
})

# layout.html # 在认证的模板文件中,修改验证

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        .shadow{
            position: fixed;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
            background-color: #0f0f0f;
            opacity: 0.5;
            z-index: 999;
        }
        .modal{
            position: fixed;
            z-index: 1000;
            top: 50%;
            left: 50%;
            width: 400px;
            height: 300px;
            margin-left: -200px;
            margin-top: -150px;
            background-color: white;
            padding: 20px;
        }
        .hide{
            display: none;
        }
    </style>
</head>
<body>
    {% if request.session.uuu %}
        <a>{{ request.session.uuu }}</a>
    {% else %}
        <a id="btn">登录</a>
    {% endif %}
    {% block content %} {% endblock %}
    <div id="sd" class="shadow hide"></div>
    <div id="md" class="modal hide">
        <form id="f11">
            {% csrf_token %}
            <p><input type="text" id="username" name="username" placeholder="用户名" /></p>
            <p><input type="password" id="pwd" name="pwd"  placeholder="密码"/></p>
        </form>
        <a id="sbm">提交</a>
        <a id="cancle">取消</a>
    </div>
    <script src="/static/jquery.js"></script>
    <script src="/static/jquery.cookie.js"></script>
    <script>
        $(function () {
            $('#btn').click(function () {
                $('#sd,#md').removeClass('hide');
            });
            $('#cancle').click(function () {
                $('#sd,#md').addClass('hide');
            });
            $('#sbm').click(function () {
                $.ajax({
                    url: '/login/',
                    type: 'POST',
                    data: $('#f11').serialize(),
                    dataType: 'JSON',
                    header: {"X-CSRFToken": $.cookie('csrftoken')},
                    success:function (arg) {
                        if(arg.status){
                            location.reload();
                        }else{
                            $.each(arg.error,function (k,v) {
                                // k = username,v = [xxxx,]
                                var tag = document.createElement('span');
                                tag.innerHTML = v[0];
                                $('#' + k).after(tag);
                            })
                        }
                    }
                })
            })
        })
    </script>
</body>
</html>
View Code

上传文件

a. Form表单上传,页面刷新

    <form action="/upload/" method="POST" enctype="multipart/form-data">
        {% csrf_token %}
        <input  type="file" name="fffff"/>
        <input type="submit" value="提交" />
    </form>

b. Ajax方式: 注:对较老的浏览器兼容性不好

$(function () {
    $('#btn1').click(function () {
        var fm = new FormData();
        fm.append('fffff', document.getElementById('ggggg').files[0]);
        fm.append('usernmae','root');
        
        $.ajax({
            url: "/ajax-upload/",
            type: 'POST',
            data: fm,
            processData: false,  // tell jQuery not to process the data
            contentType: false,  // tell jQuery not to set contentType
            success:function (arg) {
                console.log(arg);
            }
        })
    })
})

c. "伪"Ajax操作,获取iframe标签中的内容,iframe中有document的对象,并且有有预览操作,自动上传
1. iframe + Form表单
2. iframe onload
3. $('#ifr').contents().
4. 上传按钮透明度

# views.py # 上传文件的视图函数

def upload(request):
    if request.method == "GET":
        return render(request,'upload.html')
    else:
        obj = request.FILES.get('fffff')
        f = open(obj.name,'wb')
        for chunk in obj.chunks():
            f.write(chunk)
        f.close()
        return render(request, 'upload.html')
    
def ajax_upload(request):
    import os
    response = BaseReponse()
    try:
        obj = request.FILES.get('fffff')
        file_path = os.path.join('static',obj.name)
        f = open(file_path, 'wb')
        for chunk in obj.chunks():
            f.write(chunk)
        f.close()
        response.status = True
        response.data = file_path
    except Exception as e:
        response.status = False
        response.error = "上传失败"
    print(file_path)
    return HttpResponse(json.dumps(response.__dict__))
View Code

# upload.html
<iframe id="ifr" name="ifr" onload="successBack();" style="display: none"></iframe>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>Form上传文件</h1>
    <form action="/upload/" method="POST" enctype="multipart/form-data">
        {% csrf_token %}
        <input  type="file" name="fffff"/>
        <input type="submit" value="提交" />
    </form>
    <h1>Ajax上传文件</h1>
    <input  type="file" id="ggggg"/>
    <a id="btn1">提交</a>
    <h1>"伪"Ajax操作</h1>
    <form id="ff1" action="/ajax-upload/" method="POST" enctype="multipart/form-data" target="ifr">
        {% csrf_token %}
        <input  type="file" name="fffff" onchange="changeImg();"/>
    </form>

    <iframe id="ifr" name="ifr" onload="successBack();"  style="display: none"></iframe>

    <div id="prevImg"></div>

    <script src="/static/jquery.js"></script>
    <script>
        $(function () {
            $('#btn1').click(function () {
                var fm = new FormData();
                fm.append('fffff', document.getElementById('ggggg').files[0]);
                $.ajax({
                    url: "/ajax-upload/",
                    type: 'POST',
                    data: fm,
                    processData: false,  // tell jQuery not to process the data
                    contentType: false,  // tell jQuery not to set contentType
                    success:function (arg) {
                        console.log(arg);
                    }
                })
            })
        });
        function successBack() {
            var v = $('#ifr').contents().find('body').html();
            var obj = JSON.parse(v);

            var tag = document.createElement('img');
            tag.src = "/" + obj.data;

            $('#prevImg').append(tag);

        }
        function changeImg() {
            document.getElementById('ff1').submit();
        }
    </script>
</body>
</html>
View Code

 

数据库表

1.用户表 # 用户用户登录使用

class UserInfo:
    username
    pwd

2.News表 # 登录后,显示新闻

class News:
    title
    summary
    href
    news_type_choices = [
        (1, '42区')
        (1, '42区')
        (1, '42区')
    ]
    nt_id = Interager(choices=news_type_choices) # 新闻类型
    u = FK(UserInfo) # 发布者 
    ctime = models.DateTimeField(auto_now_add=True)
                # time模块

    favor = models.M2m("UserInfo")
    """ 第三那张表
    1  1 
    1  2
    1  3
    2  3
    2  2
    """
news_list = News.objects.all()
for row in news_list:
    print(row.title,summary,row.favor.all().count())

# models.py

q1
class Comment:
    id 自增: 评论ID
    content = 评论内容
    user = FK(UserInfo,related_name='q1') = 评论者ID
    new = Fk(News,related_name='q2') = 评论的文章ID
    ctime =评论时间
    parent_id = FK(Comment,related_name='q3')   自关联

1  嗯,不像我们还要担心内部打架伤了背部    10  11  null
2  突破重围,结果被KGB大佬亲手格杀.....   10  12  null
3  这几个肉会玩                         10  13  null
4  asdfasdfasdf                       10  11  null
5  开门,你的快递到了                    10  19  1

 

3.comment表 # 评论表

q1
class Comment:
    id 自增: 评论ID
    content = 评论内容
    user = FK(UserInfo,related_name='q1') = 评论者ID
    new = Fk(News,related_name='q2') = 评论的文章ID
    ctime =评论时间
    parent_id = FK(Comment,related_name='q3')   自关联

1  嗯,不像我们还要担心内部打架伤了背部    10  11  null
2  突破重围,结果被KGB大佬亲手格杀.....   10  12  null
3  这几个肉会玩                         10  13  null
4  asdfasdfasdf                       10  11  null
5  开门,你的快递到了                    10  19  1

 

posted @ 2017-06-08 17:24  huaxiayidao  阅读(59)  评论(0)    收藏  举报