标签:使用 $.ajax src 基础 忘记 asa encode _for 个数
上课第20天,打卡:
In the end, we are our choices. Build yourself a great story.
1 2017-09-10 - s17day20 2 3 内容回顾: 4 1. Http请求相关 5 6 2. Django请求生命周期 7 alert({{name}}); 8 3. Model操作 9 单表: 10 [obj,obj,obj] = models.xxx.objects.all() 11 12 [{},{},{}] = models.xxx.objects.values(‘id‘,‘name‘....) 13 14 [(),()] = models.xxx.objects.values_list(‘id‘,‘name‘....) 15 16 一对多: 17 dep部门表: 标题 (user_set) 18 19 user员工表:用户 邮箱 部门Id(FK) 20 21 22 qs = [obj,obj,obj] = models.user.objects.all() 23 for row in qs: 24 row.id,row.name,row.email,row.xx.title 25 26 [{},{},{}] = models.xxx.objects.values(‘id‘,‘name‘,‘xx__title‘) 27 [(),(),()] = models.xxx.objects.values_list(‘id‘,‘name‘,‘xx__title‘) 28 29 多对多: 30 业务线: id title M2M 31 32 33 管理员: id name (bs_set) 34 35 36 业务线和管理员关系表 37 38 obj = models.bs.objects.get(id=1) 39 40 [管理员,管理员,管理员] = obj.m2m.all() 41 42 4. 分页 43 44 5. csrf 45 46 47 6. cookie 48 保存在浏览器客户端的键值对 49 50 7. session 51 以来cookie,保存在服务器端的键值对 52 53 54 今日内容: 55 1. FBV & CBV 56 a. 57 FBV -> 函数 58 CBV -> 类 59 - dispatch 60 - get获取/post提交 61 62 b. 应用:登录验证 63 64 继承: 65 单继承: 66 # class BaseView(View): 67 # def dispatch(self, request, *args, **kwargs): 68 # if request.session.get(‘username‘): 69 # response = super(BaseView,self).dispatch(request, *args, **kwargs) 70 # return response 71 # else: 72 # return redirect(‘/login.html‘) 73 # 74 # class IndexView(BaseView): 75 # 76 # def get(self,request,*args,**kwargs): 77 # return HttpResponse(request.session[‘username‘]) 78 79 80 多继承: 81 82 # 多继承方式: 83 # class BaseView(object): 84 # def dispatch(self, request, *args, **kwargs): 85 # if request.session.get(‘username‘): 86 # response = super(BaseView,self).dispatch(request, *args, **kwargs) 87 # return response 88 # else: 89 # return redirect(‘/login.html‘) 90 # 91 # class IndexView(BaseView,View): 92 # 93 # def get(self,request,*args,**kwargs): 94 # return HttpResponse(request.session[‘username‘]) 95 96 装饰器: 97 98 def auth(func): 99 def inner(request,*args,**kwargs): 100 if request.session.get(‘username‘): 101 obj = func(request,*args,**kwargs) 102 return obj 103 else: 104 return redirect(‘/login.html‘) 105 return inner 106 107 108 # @method_decorator(auth,name=‘get‘) 109 class IndexView(View): 110 111 @method_decorator(auth) 112 def dispatch(self, request, *args, **kwargs): 113 if request.session.get(‘username‘): 114 response = super(IndexView,self).dispatch(request, *args, **kwargs) 115 return response 116 else: 117 return redirect(‘/login.html‘) 118 119 @method_decorator(auth) 120 def get(self,request,*args,**kwargs): 121 return HttpResponse(request.session[‘username‘]) 122 123 @method_decorator(csrf_exempt) # 无效 124 def post(self,request,*args,**kwargs): 125 return HttpResponse(request.session[‘username‘]) 126 127 128 特殊:CSRF 129 class IndexView(View): 130 131 @method_decorator(csrf_exempt) 132 def dispatch(self, request, *args, **kwargs): 133 return super(LoginView,self).dispatch(request, *args, **kwargs) 134 135 136 def get(self,request,*args,**kwargs): 137 return HttpResponse(request.session[‘username‘]) 138 139 140 def post(self,request,*args,**kwargs): 141 return HttpResponse(request.session[‘username‘]) 142 2. 序列化 143 方式一: 144 user_list = models.UserInfo.objects.all() 145 data = serializers.serialize("json", user_list) 146 [ 147 {"model": "app01.userinfo", "pk": 1, "fields": {"username": "\u5174\u666e", "password": "123123"}}, 148 {"model": "app01.userinfo", "pk": 2, "fields": {"username": "\u94f6\u79cb\u826f", "password": "666"}} 149 ] 150 151 方式二: 152 153 user_list = models.UserInfo.objects.values(‘id‘,‘username‘) 154 user_list = list(user_list) 155 data = json.dumps(user_list) 156 [ 157 {"username": "\u5174\u666e", "id": 1}, 158 {"username": "\u94f6\u79cb\u826f", "id": 2} 159 ] 160 161 问题:对json.dumps做定制: 162 163 import json 164 from datetime import date 165 from datetime import datetime 166 167 class JsonCustomEncoder(json.JSONEncoder): 168 def default(self, field): 169 if isinstance(field, datetime): 170 return field.strftime(‘%Y-%m-%d %H:%M:%S‘) 171 elif isinstance(field, date): 172 return field.strftime(‘%Y-%m-%d‘) 173 else: 174 return json.JSONEncoder.default(self, field) 175 176 177 user_list = [ 178 {‘id‘:1,‘name‘:‘alex‘,‘ctime‘: datetime.now()}, 179 {‘id‘:2,‘name‘:‘eric‘,‘ctime‘: datetime.now()} 180 ] 181 182 data = json.dumps(user_list,cls=JsonCustomEncoder) 183 print(data) 184 185 186 总结: 187 - 模板渲染 188 - Ajax 189 - json序列化 190 - 前端:js添加到页面 191 192 193 3. Form表单验证(用户请求验证+生成HTML标签) 194 示例:用户管理 195 a. 添加用户页面 196 - 显示HTML标签 197 - 提交:数据验证 198 - 成功之后保存 199 - 错误显示错误信息 200 201 总结: 202 1. 创建Form类(本质就是正则表达式的集合) 203 204 from django.forms import Form 205 from django.forms import fields 206 from django.forms import widgets 207 208 class UserForm(Form): 209 username = fields.CharField( 210 required=True, 211 error_messages={‘required‘:‘用户名不能为空‘}, 212 widget=widgets.TextInput(attrs={‘class‘:‘form-control‘}) 213 ) 214 password = fields.CharField( 215 required=True, 216 error_messages={‘required‘: ‘邮箱不能为空‘,‘invalid‘:‘邮箱格式错误‘}, 217 widget = widgets.TextInput(attrs={‘class‘: ‘form-control‘}) 218 ) 219 # fields.EmailField() 220 # fields.GenericIPAddressField(protocol=‘ipv4‘) 221 222 ut_id = fields.ChoiceField( 223 choices=[], 224 widget=widgets.Select(attrs={‘class‘:‘form-control‘}) 225 ) 226 227 role_id = fields.MultipleChoiceField( 228 choices=[], 229 widget=widgets.SelectMultiple(attrs={‘class‘:‘form-control‘}) 230 ) 231 232 def __init__(self,*args,**kwargs): 233 super(UserForm,self).__init__(*args,**kwargs) 234 # self.fields已经有所有拷贝的字段 235 self.fields[‘ut_id‘].choices = models.UserType.objects.values_list(‘id‘,‘title‘) 236 self.fields[‘role_id‘].choices = models.Role.objects.values_list(‘id‘,‘caption‘) 237 238 2. 只是生成HTML标签: 添加页面 239 form = MyForm() 240 241 {{form.xx}} 242 243 3. 带默认值的HTML标签: 编辑页面 244 form = MyForm(initial={‘xx‘: xxx}) 245 246 {{form.xx}} 247 248 4. 提交数据 249 form = MyForm(data=request.POST) 250 251 if form.is_valid(): 252 print(form.cleaned_data) 253 else: 254 print(form.errors) 255 256 问题:下拉框数据无法实时更新 257 class UserForm(Form): 258 username = fields.CharField( 259 required=True, 260 error_messages={‘required‘:‘用户名不能为空‘} 261 ) 262 password = fields.CharField( 263 required=True, 264 error_messages={‘required‘: ‘邮箱不能为空‘,‘invalid‘:‘邮箱格式错误‘} 265 ) 266 267 ut_id = fields.ChoiceField(choices=[]) 268 269 def __init__(self,*args,**kwargs): 270 super(UserForm,self).__init__(*args,**kwargs) 271 272 self.fields[‘ut_id‘].choices = models.UserType.objects.values_list(‘id‘,‘title‘) 273 274 275 276 示例:只用表单验证的功能(Ajax提交),注册&登录 277 278 279 定律: 280 【个数少,内容少】 281 页面摸态对话框:添加+删除+编辑 =》 ajax(无刷新) + Djaogo Form组件 282 - 验证 283 - 生成HTML(可用可不用,因为提交页面不刷新) 284 285 286 287 【适用于:数据个数多;博客】 288 新URL方式:添加+删除+编辑 =》 Form标签提交(页面刷新) + + Djaogo Form组件 289 290 - 验证 291 - 生成HTML(不用,无保留上次输入的内容) 292 293 294 个人: 295 296 - 删除利用模态对话框,确认 297 - 添加+修改: 新URL方式 298 299 300 301 302 作业:主机管理 303 304 用户表(id, user,pwd,email,mm) 305 业务线(id, name) # 用户表_set 306 主机表(id host ip port FK(业务线)) 307 用户业务线关系表(id uid bid) ****** 308 309 310 1. 登录+注册(Ajax+form组价) 311 2. FBV&CBV 312 业务线管理(列表,增加,修改) # 删除对话框确认删除 313 主机管理(列表,增加,修改) # 删除对话框确认删除 314 用户管理(列表,增加,修改) # 删除对话框确认删除 315 3. 分页 316 4. BootStrap【可选】 317 318 如何做: 319 周一 + 周二: 课上讲的内容理解 320 321 周三 : 写作业 322 323 周六: 本周不太理解+以前不理解;下午预习 324 4. 缓存 325 326 5. 中间件 327 328 6. 信号 329 330 7. Admin 331 332 333 334
################
# 2017-09-10 - 课上笔记
################
上节回顾
1.http请求周期
请求头和请求体使用 ‘\r\n\r\n‘ 分隔
2.Models操作
单表
[obj,obj,obj...] = models.xxx.objects.all()
[{},{},{}...] = models.xxx.objects.values(xx,xx,xx...)
[(),(),()...] = models.xxx.objects.values_list(xx,xx,xx...)
一对多
dep 部门表:标题
user 员工表:用户,邮箱,部门id(外键)
qs = [obj,obj,obj...] = models.user.objects.all()
for row in qs:
row.id,row.name,row.email,row.xx.title
user 查 dep
[{},{},{}...] = models.user.objects.values(‘id‘,‘name‘,‘email‘,‘xx__title‘)
[(),(),()...] = models.user.objects.values_list(‘id‘,‘name‘,‘email‘,‘xx__title‘)
dep 反查 user : user_set (在dep表里隐含的字段,多对多同样)
多对多
业务线 id name M2M
用户表 id name
django给创建第三张表(因为manytomany)
3.自定义分页模块
4.csrf
5.cookie
保存在客户端浏览器上的键值对
6.session
保存在服务器端的键值对,依赖cookie
day20今日内容
1. FBV 和 CBV
FBV:function basic view
/index/ func(request)
if "GET" == request.method:
...
CBV:class basic view
/index/ class(object)
- 判断:
get请求 就执行类里的get方法
post请求 就执行类里的post方法
form表单只能提交 ‘get‘ 和 ‘post‘ 方法
ajax 则可以提交:‘get‘, ‘post‘, ‘put‘, ‘patch‘, ‘delete‘, ‘head‘, ‘options‘, ‘trace‘
ajax 遵循resful规范
/index/ obj = 类()
找到类之后,执行完 __init__ 就执行 dispatch()方法,自己不写的话就执行父类的 dispatch()
‘‘‘
class B:
def f1(self):
self.f2()
class A(B):
def f2(self):
print("---> A")
obj = A()
obj.f1() ---> B.f1(obj) --> obj.f2()
‘‘‘
def dispatch(self, request, *args, **kwargs):
# Try to dispatch to the right method; if a method doesn‘t exist,
# defer to the error handler. Also defer to the error handler if the
# request method isn‘t on the approved list.
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
POST obj.post 是通过反射 getattr()
GET obj.get 是通过反射 getattr()
‘‘‘执行super,调用父类的dispatch方法‘‘‘
def dispatch(self, request, *args, **kwargs):
print(‘before‘)
# 执行父类的 dispatch方法
response = super(LoginView,self).dispatch(request,*args, **kwargs)
print(‘after‘)
return response
‘‘‘或者重写父类的dispatch‘‘‘
def dispatch(self, request, *args, **kwargs):
method = request.method.lower()
# print(‘+++++++++++++‘, self.http_method_names)
if hasattr(LoginView,method):
func = getattr(LoginView,method)
return func(self, request, *args, **kwargs)
else:
return HttpResponse(‘err‘)
def get(self,request,*args,**kwargs):
print(‘------->> get‘)
return render(request,‘login.html‘)
def post(self,request,*args,**kwargs):
print(‘------->> post‘)
return HttpResponse(‘ok‘)
注意:django的CBV里装饰器不能直接用,需要使用: from django.utils.decorators import method_decorator
FBV -> 函数
CBV -> 类
- dispatch
- get/post
应用:
登录验证的几种实现方法:
- 继承
- 单继承实现
‘‘‘
from django.shortcuts import render,redirect,HttpResponse
from django.views import View
from django.views.decorators.csrf import csrf_exempt,csrf_protect
from django.core import serializers
from django.utils.decorators import method_decorator
# Create your views here.
class Login(View):
def dispatch(self, request, *args, **kwargs):
return super(Login,self).dispatch(request, *args, **kwargs)
def get(self, request,*args, **kwargs):
return render(request,‘login.html‘)
def post(self, request,*args, **kwargs):
user = request.POST.get(‘user‘)
pwd = request.POST.get(‘pwd‘)
if ‘alex‘ == user and ‘123‘ ==pwd:
request.session[‘user‘] = user
return render(request,‘private.html‘,{‘user‘:user})
return render(request,‘login.html‘,{‘msg‘:‘用户名或密码错误!‘})
class Base(View):
def dispatch(self, request, *args, **kwargs):
if request.session.get(‘user‘):
response = super(Base,self).dispatch(request, *args, **kwargs)
return response
else:
return redirect(‘/login/‘)
class Index(Base):
def get(self, request,*args, **kwargs):
return render(request, ‘index.html‘, {‘user‘: request.session.get(‘user‘)})
‘‘‘
- 多继承实现
‘‘‘
class Base(object):
def dispatch(self, request, *args, **kwargs):
if request.session.get(‘user‘):
response = super(Base,self).dispatch(request, *args, **kwargs)
return response
else:
return redirect(‘/login/‘)
class Index(Base,View):
def get(self, request,*args, **kwargs):
return render(request, ‘index.html‘, {‘user‘: request.session.get(‘user‘)})
‘‘‘
- 装饰器
auth 是装饰器函数
- 加在类上 @method_decorator(auth,name=‘post‘)
‘‘‘
# 装饰器:验证用户是否已经登录
def auth(func):
def wrapper(request, *args, **kwargs):
if request.session.get(‘user‘):
obj = func(request, *args, **kwargs)
return obj
else:
return redirect(‘/login/‘)
return wrapper
@method_decorator(auth,‘get‘)
class Index(View):
def dispatch(self, request, *args, **kwargs):
return super(Index, self).dispatch(request, *args, **kwargs)
def get(self, request, *args, **kwargs):
return render(request, ‘index.html‘, {‘user‘: request.session.get(‘user‘)})
‘‘‘
- 加在dispatch上 @method_decorator(auth)
‘‘‘
# 装饰器:验证用户是否已经登录
def auth(func):
def wrapper(request, *args, **kwargs):
if request.session.get(‘user‘):
obj = func(request, *args, **kwargs)
return obj
else:
return redirect(‘/login/‘)
return wrapper
class Index(View):
@method_decorator(auth)
def dispatch(self, request, *args, **kwargs):
return super(Index, self).dispatch(request, *args, **kwargs)
def get(self, request, *args, **kwargs):
return render(request, ‘index.html‘, {‘user‘: request.session.get(‘user‘)})
‘‘‘
- 加在具体方法上 @method_decorator(auth)
‘‘‘
# 装饰器:验证用户是否已经登录
def auth(func):
def wrapper(request, *args, **kwargs):
if request.session.get(‘user‘):
obj = func(request, *args, **kwargs)
return obj
else:
return redirect(‘/login/‘)
return wrapper
class Index(View):
@method_decorator(auth)
def get(self, request, *args, **kwargs):
return render(request, ‘index.html‘, {‘user‘: request.session.get(‘user‘)})
‘‘‘
from django.views.decorators.csrf import csrf_exempt,csrf_protect
- csrf_exepmt 加在POST上例外,只能加在 dispatch上有效,官网bug。
2. 序列化 (Json是不能处理 queryset的)
- 模板渲染
- ajax
- from django.core import serializers
- serializers 的局限性:
queryset里必须是obj才可以
如果是models.xxx.objects.values(xx,xx,xx) 这样得到的queryset是不能用serializers进行序列化的!!!
只能采用在后台自己拼接好字典等形式,自己搞成json.dumps然后传给ajax
- json 序列化 (有局限性,需自定义dumps)
因为json能处理的数据类型有限,比如datetime类型就不能处理,需要自定义dumps函数
方式一:
user_list = models.UserInfo.objects.all()
data = serializers.serialize("json", user_list)
[
{"model": "app01.userinfo", "pk": 1, "fields": {"username": "\u5174\u666e", "password": "123123"}},
{"model": "app01.userinfo", "pk": 2, "fields": {"username": "\u94f6\u79cb\u826f", "password": "666"}}
]
方式二:
user_list = models.UserInfo.objects.values(‘id‘,‘username‘)
user_list = list(user_list)
data = json.dumps(user_list)
[
{"username": "\u5174\u666e", "id": 1},
{"username": "\u94f6\u79cb\u826f", "id": 2}
]
问题:json支持的数据类型有限,针对一些数据类型,例如datatime类型则不能进行序列化:
class JSONEncoder(object):
"""Extensible JSON <http://json.org> encoder for Python data structures.
Supports the following objects and types by default:
+-------------------+---------------+
| Python | JSON |
+===================+===============+
| dict | object |
+-------------------+---------------+
| list, tuple | array |
+-------------------+---------------+
| str | string |
+-------------------+---------------+
| int, float | number |
+-------------------+---------------+
| True | true |
+-------------------+---------------+
| False | false |
+-------------------+---------------+
| None | null |
+-------------------+---------------+
To extend this to recognize other objects, subclass and implement a
``.default()`` method with another method that returns a serializable
object for ``o`` if possible, otherwise it should call the superclass
implementation (to raise ``TypeError``).
"""
...
解决办法:对json.dumps做定制:
import json
from datetime import date
from datetime import datetime
class JsonCustomEncoder(json.JSONEncoder):
def default(self, field):
if isinstance(field, datetime):
return field.strftime(‘%Y-%m-%d %H:%M:%S‘)
elif isinstance(field, date):
return field.strftime(‘%Y-%m-%d‘)
else:
return json.JSONEncoder.default(self, field)
user_list = [
{‘id‘:1,‘name‘:‘alex‘,‘ctime‘: datetime.now()},
{‘id‘:2,‘name‘:‘eric‘,‘ctime‘: datetime.now()}
]
data = json.dumps(user_list,cls=JsonCustomEncoder)
print(data)
ajax扩展:
从后端获得的字符串: JSON.parse() 可以被 dataType: ‘JSON‘ 这一行替换:
# 后端代码:
...
import json
return HttpResponse(json.dumps({‘flag‘:True,‘msg‘:‘ok‘}))
...
示例1:使用JSON.parse()的情况,返回的是 object类型
<form id="my_form" action="/login/" method="post">
{% csrf_token %}
<input type="text" name="user">
<input type="password" name="pwd">
<button onclick="ajaxSubmit()">Ajax提交</button>
</form>
<script src="{% static "js/jquery-3.2.1.min.js" %}"></script>
<script src="{% static "js/jquery.cookie.js" %}"></script>
<script src="{% static "js/bootstrap.js" %}"></script>
<script>
function ajaxSubmit() {
$.ajax({
url:‘/login/‘,
type:‘POST‘,
data:{
‘user‘:$(‘#my_form input[name="user"]‘).val(),
‘pwd‘:$(‘#my_form input[name="pwd"]‘).val()
},
headers:{‘X-CSRFToken‘: $.cookie(‘csrftoken‘)},
success:function (data) {
var info = JSON.parse(data);
console.log(info);
console.log(typeof info);
}
})
}
</script>
示例2:使用dataType: ‘JSON‘的情况,返回的是string类型
<form id="my_form" action="/login/" method="post">
{% csrf_token %}
<input type="text" name="user">
<input type="password" name="pwd">
<button onclick="ajaxSubmit()">Ajax提交</button>
</form>
<script src="{% static "js/jquery-3.2.1.min.js" %}"></script>
<script src="{% static "js/jquery.cookie.js" %}"></script>
<script src="{% static "js/bootstrap.js" %}"></script>
<script>
function ajaxSubmit() {
$.ajax({
url:‘/login/‘,
type:‘POST‘,
datatype:‘JSON‘,
data:{
‘user‘:$(‘#my_form input[name="user"]‘).val(),
‘pwd‘:$(‘#my_form input[name="pwd"]‘).val()
},
headers:{‘X-CSRFToken‘: $.cookie(‘csrftoken‘)},
success:function (info) {
console.log(info);
console.log(typeof info);
}
})
}
</script>
3. Django的Form表单验证(用户请求的验证 + 生成HTML标签)
示例:用户管理
添加用户页面:
- 显示HTML标签
- 提交:数据验证
- 成功之后保存
- 错误的话则提示错误信息
from django.forms import widgets 样式
总结:
1. 创建类 MyForm(本质就是正则表达式的集合),继承Form类
2. 只是生成HTML标签:form = MyForm() 添加页面
3. 带默认值的HTML标签:form = MyForm(initial={‘xx‘:‘xx‘,...}) 编辑页面
4. 提交数据:form = Form(data=request.POST)
if form.is_valid():
print(form.cleaned_data)
else:
print(form.errors)
5. 存在的问题:下拉框有更新时无法实时更新到前端页面
解决办法:重写下 __init__(self,*args,**kwargs)
‘‘‘
class UserForm(Form):
user = fields.CharField(required=True,error_messages={‘required‘:‘用户名不能为空‘})
pwd = fields.CharField(required=True,error_messages={‘required‘:‘密码不能为空‘})
email = fields.EmailField(required=True,error_messages={‘required‘:‘邮箱不能为空‘,‘invalid‘:‘邮箱格式不正确‘})
# user_type = models.UserType.objects.values_list(‘id‘,‘title‘)
# user_type = list(user_type)
ut_id = fields.ChoiceField(choices=[])
role_id = fields.MultipleChoiceField(choices=[])
# ip = fields.GenericIPAddressField(required=True)
# 解决下拉框数据更新后,前端页面不更新的问题
def __init__(self,*args,**kwargs):
super(UserForm,self).__init__(*args,**kwargs)
self.fields[‘ut_id‘].choices = models.UserType.objects.values_list(‘id‘,‘title‘)
self.fields[‘role_id‘].choices = models.Role.objects.values_list(‘id‘,‘caption‘)
‘‘‘
一对多
多对多
三元运算:v = xxx if xxx else []
找name等于user的input标签
$(‘#f1 input[name="user"]‘).val(‘xxxxx‘)
$(‘#f1 .error‘).remove()
input标签后提示错误信息:
$.each(arg.msg, function(k,v){
var tag = document.createFlement(‘span‘);
tag.innerHTML = v[0];
tar.className = "error"
# <span class=‘error‘>v[0]</span>
$(‘#f1 input[name="‘ + k + ‘user"]‘).after(tag)
})
定律:
如果用模态对话框进行添加或者修改等操作,则前端提交数据需要用ajax,后端可以用django的form组件
因为ajax不刷新,所以可以利用form组件的验证功能,生成HTML的功能可用可不用
如果用新的页面进行添加或者修改等操作,则用ajax和form表单提交都可以;后端可以用django的form组件
因为form有刷新,生成HTML的功能要使用,不可以自己手写HTML标签,避免之前的数据因为刷新导致丢失;
4. 缓存
5. 中间件
6. 信号(scrapy爬虫框架里有用)
7. Django的 Admin
JS跳转页面的方法:location.href = ‘/index.html‘
day20作业:
还是主机管理
1. 登录 + 注册(ajax+form组件)
FBV / CBV 都可以
2. 业务线管理(列表、增加、修改 页面跳转) 模态确认删除 单表
3. 主机管理(列表、增加、修改 页面跳转) 模态确认删除 一对多
4. 用户管理(列表、增加、修改 页面跳转) 模态确认删除 多对多
5. 自定义分页
6. Bootstrap
把课上讲的内容搞明白,还有几个之前忘记的点,今天老师写的;
然后开始做作业;
周六上午,整理出遇到的问题;
‘‘‘‘‘‘
# shell in a box 插件
三元运算符 列表推导式 生成器推导式
标签:使用 $.ajax src 基础 忘记 asa encode _for 个数
原文地址:http://www.cnblogs.com/standby/p/7508120.html