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次单表操作
二、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})
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>
五、信号
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)
# 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})
# 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>
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})
# 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>
# 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))
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)
# 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)
# 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>
抽屉页面分析
一、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/')
# 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>
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')
#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>
# 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>
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>
上传文件
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__))
# 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>
数据库表
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

浙公网安备 33010602011771号