Django web 进阶
、路由系统 、模板引擎 simple_tag 、Form 、Ajax请求 -简单数据 -复杂数据 内容:
-作业 model xss、csrf(安全方面的内容) 分页(公共的模块)
内容复习和今日内容
Django静态文件引用优化
存在两种引用方式:
1、方式1
2、方式2
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'django.core.context_processors.static', #新增的内容
],
},
},
] STATIC_URL = '/static/'
settings
为什么?
def static(request):
"""
Adds static-related context variables to the context.
"""
return {'STATIC_URL': settings.STATIC_URL}
from django.core.context_processors import static
对于views文件和templates来讲,在涉及较大量的时候,都应该进行分类处理,比如views\account.py类处理登录的函数,templates\account下的html文件为登录相关的html文件,如下
from django.conf.urls import url,include
from django.contrib import admin urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include("app01.urls")),
]
urls
from django.conf.urls import url,include
from django.contrib import admin
from app01.views import account urlpatterns = [
url(r'^login/', account.login),
]
app01/urls
#!/usr/bin/env python
# _*_ coding:utf- _*_ from django.shortcuts import render
def login(request):
return render(request, "account/login.html")
account.py
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>abcd</h1>
<h1>{{ STATIC_URL }}</h1>
<script src="/static/js/jquery-2.1.4.min.js"></script>
<script src="{{ STATIC_URL }}js/jquery-2.1.4.min.js"></script>
<script src="{% static "js/jquery-2.1..min.js"%}"></script> </body>
</html>
login.html
Form基本功能应用之保存用户输入内容
1、对于不同的函数使用的form,应该进行分类:
#!/usr/bin/env python
# _*_ coding:utf- _*_ from django import forms
class LoginForm(forms.Form):
username = forms.CharField() #字符串
password = forms.CharField(widget=forms.PasswordInput) #没有字符串的设定格式,通过widget进行设置
form\account.py
2、普通render方式如下,无法保存用户输入内容
点击submit之后,如果用户密码或用户名输入错误,密码和用户名输入框就会都变为空;
#!/usr/bin/env python
# _*_ coding:utf- _*_ from django.shortcuts import render
from app01.forms import account as AccountForm
def login(request):
'''
if request.method == "POST":
inp_obj = AccountForm.LoginForm(request.POST) #封装了数据的对象,不仅可以做数据的验证,还可以将提交的数据再次显示到页面上去;
return render(request, "account/login.html",{'obj':inp_obj})'''
obj = AccountForm.LoginForm()
return render(request, "account/login.html",{'obj':obj}) #没有封装数据的对象
views\account.py
采用如下方式,会保存用户名:
#!/usr/bin/env python
# _*_ coding:utf- _*_ from django.shortcuts import render
from app01.forms import account as AccountForm #为了区分views的account,使用as
def login(request):
'''1、第一次登陆为get,不会执行if部分'''
if request.method == "POST":
inp_obj = AccountForm.LoginForm(request.POST) #封装了数据的对象,不仅可以做数据的验证,还可以将提交的数据再次显示到页面上去;
return render(request, "account/login.html",{'obj':inp_obj})
obj = AccountForm.LoginForm()
return render(request, "account/login.html",{'obj':obj}) #没有封装数据的对象
views/account.py
或者:
#!/usr/bin/env python
# _*_ coding:utf- _*_ from django.shortcuts import render
from app01.forms import account as AccountForm #为了区分views的account,使用as
def login(request):
obj = AccountForm.LoginForm(request.POST) #获取页面输入的数据
if request.method == "POST":
return render(request, "account/login.html",{'obj':obj})
return render(request, "account/login.html",{'obj':obj})
views/account.py
Form基本功能应用之验证以及错误信息
下面利用form对于post提交的数据进行验证
对于error信息,有三种输出形式:
1、as_ul
2、as_data:用于form,和不用as_data相同;
3、as_json:用于Ajax;
#!/usr/bin/env python
# _*_ coding:utf- _*_ from django.shortcuts import render,HttpResponse
from app01.forms import account as AccountForm #为了区分views的account,使用as
def login(request):
obj = AccountForm.LoginForm(request.POST) #获取页面输入的数据
if request.method == "POST":
if obj.is_valid():
all_data = obj.clean()
else:
#Form表单提交
error = obj.errors
print type(error)
print error['username'],type(error['username'])
print error['username'][],type(error['username'][])
print error['username'][]
print error['password'][]
'''
、as_ul
、as_data
、as_json
'''
#Ajax
#error = obj.errors.as_json()
#return HttpResponse(error)
#print error,type(error)
return render(request, "account/login.html",{'obj':obj,'error':error})
return render(request, "account/login.html",{'obj':obj}) #form返回obj对象
#如果是ajax的话,return HttpReponse("字符串或者字符串类型的字典,不能为obj对象")
views\account.py
{% load staticfiles %}
{% load xx %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/login/" method="post">
<p>{{ obj.username }}
<span style="color: red;">{% error_msg error.username %}</span> #因为模板语言不支持obj.username[]的方式取第一个错误信息,所以通过simple_tag来实现
</p>
<p>{{ obj.password }}</p>
<input type="submit" value="submit" /> </form>
<h1>abcd</h1>
<script src="/static/js/jquery-2.1.4.min.js"></script>
<script src="{% static "js/jquery-2.1..min.js"%}"></script>
<script> </script> </body>
</html>
login.html
#!/usr/bin/env python
# _*_ coding:utf- _*_
from django import template
from django.utils.safestring import mark_safe
from django.template.base import resolve_variable, Node, TemplateSyntaxError register = template.Library()
@register.simple_tag
def error_msg(error_list):
if error_list:
return error_list[]
return ""
templatetags\xx.py
下面利用Ajax推数据进行提交:
#!/usr/bin/env python
# _*_ coding:utf- _*_ from django.shortcuts import render,HttpResponse
from app01.forms import account as AccountForm #为了区分views的account,使用as
def login(request):
obj = AccountForm.LoginForm(request.POST) #获取页面输入的数据
if request.method == "POST":
if obj.is_valid():
all_data = obj.clean()
else:
#Form表单提交
error = obj.errors
print type(error)
#print error['username'],type(error['username'])
#print error['username'][],type(error['username'][])
#print error['username'][]
#print error['password'][]
'''
、as_ul
、as_data
、as_json
'''
#Ajax
error = obj.errors.as_json()
return HttpResponse(error)
print error,type(error)
return render(request, "account/login.html",{'obj':obj,'error':error})
return render(request, "account/login.html",{'obj':obj}) #form返回obj对象
#如果是ajax的话,return HttpReponse("字符串或者字符串类型的字典,不能为obj对象")
views\account.py
{% load staticfiles %}
{% load xx %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/login/" method="post">
<p>{{ obj.username }}
<span style="color: red;">{% error_msg error.username %}</span>
</p>
<p>{{ obj.password }}</p>
<input type="submit" value="submit" />
<input type="button" onclick="SubmitAjax();" value="Ajax" /> </form>
<h1>abcd</h1>
<script src="/static/js/jquery-2.1.4.min.js"></script>
<script src="{% static "js/jquery-2.1..min.js"%}"></script>
<script>
function SubmitAjax(){
$.ajax({
'url':'/login/',
type:'POST',
data: {'username':'','password':''},
success:function(arg){
console.log(arg);
}
})
} </script> </body>
</html>
login.html
Form功能应用之自动生成select标签
#!/usr/bin/env python
# _*_ coding:utf- _*_
from django.shortcuts import render
from app01.forms import home as HomeForm
def index(request):
obj = HomeForm.ImportForm()
return render(request,'home/index.html',{'obj':obj})
views\home.py
#!/usr/bin/env python
# _*_ coding:utf- _*_ from django import forms
class ImportForm(forms.Form):
HOST_TYPE_LIST = (
(,'物理机'),
(,'虚拟机')
)
host_type = forms.IntegerField(
widget=forms.Select(choices=HOST_TYPE_LIST)
)
hostname = forms.CharField()
import json
'''
f = open('db_admin','w')
dic = ((,"Charles"),(,"wahaha")) f.write(json.dumps(dic))
f.close()
'''
fr = open('db_admin')
data = fr.read()
print data,type(data)
data_tuple = json.loads(data)
fr.close()
admin = forms.IntegerField(
widget=forms.Select(choices=data_tuple)
)
'''如果没有下面的构造方法,在配置文件db_admin内容修改之后,select下面选择的内容不会改变;
原因是根据类的定义,其静态字段在程序启动的时候会在内存中加载一次之后不会再改变,除非类重新加载(程序重启)
因为静态字段是存在于类中的,而对于self.的方法,其存在于对象中,在对象被重新赋值的时候,值会改变,这样可以在刷新页面的
时候,select下面的选择内容会改变'''
def __init__(self, *args, **kwargs):
super(ImportForm, self).__init__(*args, **kwargs)
fr = open('db_admin')
import json
data = fr.read()
print data,type(data)
data_tuple = json.loads(data)
fr.close()
self.fields['admin'].widget.choices = data_tuple
forms\home.py
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>录入数据</h1>
<form action="/index/">
<p>{{ obj.host_type }}</p>
<p>{{ obj.hostname }}</p>
<p>{{ obj.admin }}</p>
</form>
<h1>数据列表</h1> </body>
</html>
index.html
[[, "Charles"], [, "www"],[,"ddddd"],[,"gggggg"]]
db_admin
Form功能之生成动态select标签
上述代码可以进行优化:
#!/usr/bin/env python
# _*_ coding:utf- _*_ from django import forms
class ImportForm(forms.Form):
HOST_TYPE_LIST = (
(,'物理机'),
(,'虚拟机')
)
host_type = forms.IntegerField(
widget=forms.Select(choices=HOST_TYPE_LIST)
)
hostname = forms.CharField()
admin = forms.IntegerField(
widget=forms.Select() #获取空值,在下面执行__init__方法的时候重新赋值
)
'''如果没有下面的构造方法,在配置文件db_admin内容修改之后,select下面选择的内容不会改变;
原因是根据类的定义,其静态字段在程序启动的时候会在内存中加载一次之后不会再改变,除非类重新加载(程序重启)
因为静态字段是存在于类中的,而对于self.的方法,其存在于对象中,在对象被重新赋值的时候,值会改变,这样可以在刷新页面的
时候,select下面的选择内容会改变'''
def __init__(self, *args, **kwargs):
super(ImportForm, self).__init__(*args, **kwargs)
fr = open('db_admin') #在使用models的时候,可以使用数据库获取数据
import json
data = fr.read()
print data,type(data)
data_tuple = json.loads(data)
fr.close()
self.fields['admin'].widget.choices = data_tuple
forms\home.py
Model创建表之基础字段:
model中的数据库的错做为ORM;数据库通过model中的类表示,对象为其中的一行数据,对象.id ,对象.value为每行里面的数据;
其中settings中配置数据库:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
#!/usr/bin/env python
#coding:utf-
from __future__ import unicode_literals
from django.db import models # Create your models here.
#ORM
#类-->数据库
#对象-->一行数据
#对象.id 对象.value -->每行里面的数据 class UserInfo(models.Model): #默认情况下,表会生成两列
name = models.CharField(max_length=)
ctime = models.DateTimeField(auto_now=True) #创建时间字段,数据为当前时间
uptime = models.DateTimeField(auto_now_add=True) #更新数据,日期自动添加
email1 = models.EmailField(max_length=,null=True) #表中添加一列,数据为null
email2 = models.EmailField(max_length=,default='123@123.com') #表中添加一列,数据为'123@123.com'
def __unicode__(self): #输出对象的时候,输出数据库中一行数据为name的一列
return self.name
app01\model
#!/usr/bin/env python
# _*_ coding:utf- _*_
from django.shortcuts import render
from app01.forms import home as HomeForm
from app01 import models
def index(request):
models.UserInfo.objects.all().delete() #删除数据
before = models.UserInfo.objects.all() #获取所有数据
models.UserInfo.objects.create(name = 'Charles') #添加数据
after = models.UserInfo.objects.all() print before
print after
print after[].ctime
obj = HomeForm.ImportForm()
return render(request,'home/index.html',{'obj':obj})
views\home.py
python manage.py syncdb命令同步数据库表,需要事先将app注册到settings中;
#!/usr/bin/env python
#coding:utf-
from __future__ import unicode_literals
from django.db import models # Create your models here.
#ORM
#类-->数据库
#对象-->一行数据
#对象.id 对象.value -->每行里面的数据 class UserInfo(models.Model): #默认情况下,表会生成两列
name = models.CharField(max_length=)
ctime = models.DateTimeField(auto_now=True) #创建时间字段,数据为当前时间
uptime = models.DateTimeField(auto_now_add=True) #更新数据,日期自动添加
email1 = models.EmailField(max_length=,null=True) #表中添加一列,数据为null
email2 = models.EmailField(max_length=,default='123@123.com') #表中添加一列,数据为'123@123.com'
ip=models.GenericIPAddressField(protocol="ipv4")
img = models.ImageField(null=True,blank=True,upload_to="upload") #blank=True表示在admin后台管理的时候允许为空 upload_to表示图片上传的路径,默认会自动创建 def __unicode__(self): #输出对象的时候,输出数据库中一行数据为name的一列
return self.name
app01\model.py
通过admin来管理数据库表:
from django.contrib import admin # Register your models here.
from app01 import models
admin.site.register(models.UserInfo)
app01\admin.py
Model创建表之字段参数:
、models.AutoField 自增列 = int()
如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。
、models.CharField 字符串字段
必须 max_length 参数
、models.BooleanField 布尔类型=tinyint()
不能为空,Blank=True
、models.ComaSeparatedIntegerField 用逗号分割的数字=varchar
继承CharField,所以必须 max_lenght 参数
、models.DateField 日期类型 date
对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
、models.DateTimeField 日期类型 datetime
同DateField的参数
、models.Decimal 十进制小数类型 = decimal
必须指定整数位max_digits和小数位decimal_places
、models.EmailField 字符串类型(正则表达式邮箱) =varchar
对字符串进行正则表达式
、models.FloatField 浮点类型 = double
、models.IntegerField 整形
、models.BigIntegerField 长整形
integer_field_ranges = {
'SmallIntegerField': (-, ),
'IntegerField': (-, ),
'BigIntegerField': (-, ),
'PositiveSmallIntegerField': (, ),
'PositiveIntegerField': (, ),
}
、models.IPAddressField 字符串类型(ip4正则表达式)
、models.GenericIPAddressField 字符串类型(ip4和ip6是可选的)
参数protocol可以是:both、ipv4、ipv6
验证时,会根据设置报错
、models.NullBooleanField 允许为空的布尔类型
、models.PositiveIntegerFiel 正Integer
、models.PositiveSmallIntegerField 正smallInteger
、models.SlugField 减号、下划线、字母、数字
、models.SmallIntegerField 数字
数据库中的字段有:tinyint、smallint、int、bigint
、models.TextField 字符串=longtext
、models.TimeField 时间 HH:MM[:ss[.uuuuuu]]
、models.URLField 字符串,地址正则表达式
、models.BinaryField 二进制
、models.ImageField 图片
、models.FilePathField 文件 更多字段
更多字段参数
AutoField()
BooleanField()
CharField()
CommaSeparatedIntegerField()
DateField()
DateTimeField()
DecimalField()
EmailField()
FilePathField()
FloatField()
IntegerField()
BinIntegerField()
IPAddressField()
TextField()
TimeField()
URLField()
BinaryField()
model字段
下面介绍通过Django上传文件示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="/upload/" method="POST" enctype="multipart/form-data"> //enctype="multipart/form-data"表示多个文件上传
<p><input type="file" name="f1"/></p>
<p><input type="file" name="f2"/></p>
<p><input type="text" name="hostname"/></p>
<input type="submit" value="upload"/>
</form>
</body>
</html>
template/home/upload.html
def upload(request):
if request.method=='POST':
inp_post = request.POST #获取所有的text文本信息
inp_files=request.FILES #获取所有的上传的文件信息
file_obj1 = inp_files.get('f1')
print file_obj1.name,type(file_obj1) #获取上传文件的文件名
print ''
print inp_post
f = open(file_obj1.name,'wb')
for line in file_obj1.chunks(): #chunks表示将文件进行切片,然后写入通过内存写入文件
f.write(line)
f.close() return render(request,'home/upload.html')
app01/views/home.py
Model创建表之一对多:外键,让两张表建立关系;
#!/usr/bin/env python
#coding:utf-
from __future__ import unicode_literals
from django.db import models # Create your models here.
#ORM
#类-->数据库
#对象-->一行数据
#对象.id 对象.value -->每行里面的数据 class UserInfo(models.Model): #默认情况下,表会生成两列
USER_TYPE_LIST=(
(,'f'),
(,'m'),
)
user_type = models.IntegerField(choices=USER_TYPE_LIST,default=)
name = models.CharField(max_length=,primary_key=True,verbose_name="姓名",unique=True)
ctime = models.DateTimeField(auto_now=True,) #创建时间字段,数据为当前时间
uptime = models.DateTimeField(auto_now_add=True,db_column="SB") #更新数据,日期自动添加
email1 = models.EmailField(max_length=,null=True) #表中添加一列,数据为null
email2 = models.EmailField(max_length=,default='123@123.com') #表中添加一列,数据为'123@123.com'
ip=models.GenericIPAddressField(protocol="ipv4")
img = models.ImageField(null=True,blank=True,upload_to="upload") #blank=True表示在admin后台管理的时候允许为空 def __unicode__(self): #输出对象的时候,输出数据库中一行数据为name的一列
return self.name class Color(models.Model):
name = models.CharField(max_length=) class Somthing(models.Model):
c1 = models.CharField(max_length=)
c2 = models.CharField(max_length=)
c3 = models.CharField(max_length=)
c4 = models.CharField(max_length=)
color = models.ForeignKey(Color) #将两张表通过外键进行关联 class Business(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=) class Host(models.Model):
hostname = models.CharField(max_length=)
business = models.ForeignKey('Business',to_field='nid') #指定app01business表的nid列为外键
app01/model.py
>python manage.py makemigrations
python manage.py migrate
更新表结构;
Model创建表之多对多:一个人可以属于多个组,一个组可以包含多个人;
需要创建第三张表,关联用户ID和组ID;
class UserGroup(models.Model):
group_name = models.CharField(max_length=) class User(models.Model):
name = models.CharField(max_length=)
email = models.CharField(max_length=)
mobile = models.CharField(max_length=)
user_user_group= models.ManyToManyField('UserGroup') #创建的第三张表,将UserGroup表id和User表的id进行关联
app01/model.py
Model创建表之一对一:实际在数据库表创建的时候不存在;同一张表的同一列不能有重复的数据,否则不能insert进去;就是在一对多的基础上加上了不能重复的要求;
比如用户名:密码:id等不能重复;
class User2(models.Model):
name = models.CharField(max_length=)
email = models.CharField(max_length=)
mobile = models.CharField(max_length=) class AAdmin(models.Model):
username = models.CharField(max_length=)
password = models.CharField(max_length=)
user_info = models.OneToOneField('User2') #一对一两张表关联
app01/model.py
Model操作表之基础操作
增:
model.Tb1.objects.create(c1='xx',c2='oo')
或者
obj = model.Tb1(c1='xx',c2='oo')
obj.save()
或者
dic = {'c1':'xx','c2':'oo'} #可以将form提交的数据传入
model.Tb1.objects.create(**dic)
增
查:
model.Tb1.objects.get(id=) #获取一行,如果不存在,抛异常
model.Tb1.objects.all() #获取全部
model.Tb1.objects.filter(name='seven','gender':'') #获取数据,可以用**dic替代括号中的内容 model.Tb1.objects.all().first() #获取第一条数据
删:
model.Tb1.objects.filter(name='seven').delete()
删
改:
model.Tb1.objects.filter(name='seven').update(gender='') #括号中的内容都可以通过**dic来替代 或者:
obj=model.Tb1.objects.get(id=) #获取对象
obj.c1=''
obj.save()
改
好了,上面是关于表操作的基础部分,下面开始介绍如何在实际中操作:
1、创建表SimpleModel
class SimpleModel(models.Model):
username = models.CharField(max_length=)
password = models.CharField(max_length=)
app01/model.py
2、表数据的增加和查询:
#!/usr/bin/env python
# _*_ coding:utf- _*_
from django.shortcuts import render
from app01.forms import home as HomeForm
from app01 import models
def index(request):
dic = {'username':'QQ','password':''}
models.SimpleModel.objects.create(**dic)
ret = models.SimpleModel.objects.all()
print ret,type(ret),ret.query
ret = models.SimpleModel.objects.all().values('username')
print ret,type(ret)
ret = models.SimpleModel.objects.all().values_list('username')
print ret,type(ret)
ret = models.SimpleModel.objects.all().values_list('id','username')
print ret,type(ret)
obj = HomeForm.ImportForm()
return render(request,'home/index.html',{'obj':obj})
app01/views/home.py
3、替代之前将select的内容写入配置文件中的方式,采用数据库的方式:app01/forms/home.py
from django import forms
from app01 import models
class ImportForm(forms.Form):
HOST_TYPE_LIST = (
(,'物理机'),
(,'虚拟机')
)
host_type = forms.IntegerField(
widget=forms.Select(choices=HOST_TYPE_LIST)
)
hostname = forms.CharField()
admin = forms.IntegerField(
widget=forms.Select() #获取空值,在下面执行__init__方法的时候重新赋值
)
'''如果没有下面的构造方法,在配置文件db_admin内容修改之后,select下面选择的内容不会改变;
原因是根据类的定义,其静态字段在程序启动的时候会在内存中加载一次之后不会再改变,除非类重新加载(程序重启)
因为静态字段是存在于类中的,而对于self.的方法,其存在于对象中,在对象被重新赋值的时候,值会改变,这样可以在刷新页面的
时候,select下面的选择内容会改变'''
def __init__(self, *args, **kwargs):
super(ImportForm, self).__init__(*args, **kwargs)
self.fields['admin'].widget.choices = models.SimpleModel.objects.all().values_list('id','username')
'''
fr = open('db_admin') #在使用models的时候,可以使用数据库获取数据
import json
data = fr.read()
print data,type(data)
data_tuple = json.loads(data)
fr.close()
self.fields['admin'].widget.choices = data_tuple
4、将该数据库可以通过admin后台进行管理:
from django.contrib import admin # Register your models here.
from app01 import models
admin.site.register(models.UserInfo)
admin.site.register(models.SimpleModel)
app01/admin.py
Admin定制:
class School(models.Model):
name = models.CharField(max_length=128,unique=True)
city = models.CharField(max_length=64)
addr = models.CharField(max_length=128) def __unicode__(self):
return self.name class UserProfile(models.Model):
user = models.OneToOneField(User) #alex
name = models.CharField(max_length=64)
school = models.ForeignKey('School') class ClassList(models.Model):
course = models.ForeignKey(Course,verbose_name=u"课程")
semester = models.IntegerField(verbose_name=u"学期")
course_type = models.CharField(max_length=64,choices=course_type_choices,default='offline_weekend')
teachers = models.ManyToManyField(UserProfile)
start_date = models.DateField()
graduate_date = models.DateField()
定制代码如下:
from django.contrib import admin
import models
# Register your models here. class UserProfileAdmin(admin.ModelAdmin):
list_display = ('id','user','name','school') #定义要显示的字段,不能是多对多的字段
search_fields = ('name','school__name') #可以被搜索的字典,如果是通过外键关联,使用__表示
list_filter = ('name','school__name') #定义右侧通过哪些字段过滤出来的内容
list_editable = ('name','user','school') #定义哪些字段可以直接被编辑的
list_per_page = 10 #定义每页显示几行数据
raw_id_fields = ('user','school') #如果是通过外键关联的字段,可能存在许多选择的内容,优化选择 class ClassListAdmin(admin.ModelAdmin):
list_display = ('course','semester','course_type','start_date','graduate_date')
filter_horizontal = ('teachers',) #多对多的字段,显示更加明显
admin.site.register(models.UserProfile,UserProfileAdmin)
admin.site.register(models.Customer)
admin.site.register(models.CustomerTrackRecord)
admin.site.register(models.ClassList,ClassListAdmin)
admin.site.register(models.Course)
admin.site.register(models.CourseRecord)
admin.site.register(models.StudyRecord)
admin.site.register(models.School)
还有xadmin可以定制化漂亮的admin展示,有兴趣可以自己查!!
自定义Admin action
默认的admin action只要批量选择删除的功能,action只有在批量的时候才会有用;
def changeschool(modelAdmin,request,queryset):
print '--->',request,queryset
queryset.update(school=2)
changeschool.short_description=u'set 2' def changeschool1(modelAdmin,request,queryset):
print '--->',request,queryset
queryset.update(school=1)
changeschool1.short_description=u'set 1' class UserProfileAdmin(admin.ModelAdmin):
list_display = ('id','user','name','school')
search_fields = ('name','school__name')
list_filter = ('name','school__name')
list_editable = ('name','user','school')
list_per_page = 10
raw_id_fields = ('user','school')
actions = [changeschool,changeschool1,]
Admin定制之加颜色
首先在model中定义方法:
class Customer(models.Model):
qq = models.CharField(max_length=64,unique=True)
name = models.CharField(verbose_name=u"姓名",max_length=32,blank=True,null=True)
phone = models.BigIntegerField(blank=True,null=True)
course = models.ForeignKey('Course') course_type = models.CharField(max_length=64,choices=course_type_choices,default='offline_weekend')
consult_memo = models.TextField()
source_type_choices = (('qq',u"qq群"),
('referral',u"内部转介绍"),
('51cto',u"51cto"),
('agent',u"招生代理"),
('others',u"其它"),
) source_type = models.CharField(max_length=64,choices=source_type_choices) def choice_source(self):
if self.source_type == 'qq':
format_td = format_html('<span style="padding:2px;background-color:pink;color:white"> %s</span>' %self.source_type)
elif self.source_type == 'referral':
format_td = format_html('<span style="padding:2px;background-color:pink;color:white"> %s</span>'%self.source_type)
else: format_td = format_html('<span style="padding:2px;background-color:pink;color:blank"> %s</span>' %self.source_type)
return format_td choice_source.short_description='source_type' #修改admin显示的字段
将定义的函数注册到Admin中:
class CustomerAdmin(admin.ModelAdmin):
list_display = ('source_type','choice_source')
效果如下:
Model操作表之进阶操作:
获取个数:
models.Tb1.objects.filter(name='seven').count() 大于,小于
models.Tb1.objects.filter(id__gt=)
models.Tb1.objects.filter(id__lt=)
models.Tb1.objects.filter(id__lt=,id_gt=) in
models.Tb1.objects.flter(id__in=[,,])
models.Tb1.objects.exclude(id__in=[,,]) contains 类似于like
models.Tb1.objects.filter(name__contains="ven")
models.Tb1.objects.filter(name__icontains="ven") #icontains大小写不敏感
models.Tb1.objects.exclude(name__icontains="ven") range 范围
models.Tb1.objects.filter(id__range=[,]) #between and 其他类似:
startwith,istartwith,endswith,iendswith order by
models.Tb1.objects.filter(name='seven').order_by('id') #asc
models.Tb1.objects.filter(name='seven').order_by('-id') #desc limit、offset
models.Tb1.objects.all()[:] group by
from django.db.models import Count,Min,Max,Sum
models.Tb1.objects.filter(c1=).values(id).annotate(c=Count('num'))
models.Tb1.objects.all().values(id).annotate(c=Count('num')) #以id进行分组,并计算相同组的num的最大值、最小值、和、个数等;
连表操作(数据库数据插入和数据查询展示),一对多操作
1、创建用户组表和用户组表,并通过外键进行关联
class UserGroup_NEW(models.Model):
caption = models.CharField(max_length=)
def __unicode__(self):
return self.caption class User_NEW(models.Model):
username = models.CharField(max_length=)
user_group = models.ForeignKey('UserGroup_NEW') #默认创建的外键会加上_id,可以使用db_clomn来修改为自定义的列名
def __unicode__(self):
return self.username
app01/models.py
2、form
#!/usr/bin/env python
# _*_ coding:utf- _*_ from django import forms
from app01 import models
class UserForm(forms.Form):
username = forms.CharField()
user_group_id = forms.IntegerField( #采用方式2直接插入数据的话,需要加_id
widget=forms.Select() #获取空值,在下面执行__init__方法的时候重新赋值
)
def __init__(self, *args, **kwargs):
super(UserForm, self).__init__(*args, **kwargs)
self.fields['user_group_id'].widget.choices = models.UserGroup_NEW.objects.all().values_list('id','caption')
app01/forms/foreign.py
3、数据插入方式有两种:a、通过对象插入;b、直接插入;
#!/usr/bin/env python
# _*_ coding:utf- _*_
from django.shortcuts import HttpResponse,render
from app01 import models
from app01.forms import foreign as ForgienForm
def create_user_group(request):
# models.UserGroup_NEW.objects.create(caption='CEO') #向用户组中添加数据
# models.UserGroup_NEW.objects.create(caption='CTO')
# models.UserGroup_NEW.objects.create(caption='COO')
return HttpResponse('ok') def create_user(request):
obj = ForgienForm.UserForm(request.POST)
if request.method =="POST":
print "数据提交"
#print request.POST
if obj.is_valid():
all_data = obj.clean()
print all_data
#获取对象
# group_obj = models.UserGroup_NEW.objects.get(all_data['use_group']) 方式1 通过对象级别插入数据,group_obj代表对象,是一列数据
# models.User_NEW.objects.create(hostname=all_data['username'],
# user_group=group_obj)
# models.User_NEW.objects.create(hostname=all_data['username'],
# user_group_id=all_data['user_group']) #方式2:可以通过两种方式插入数据,默认在Django中插入外键会加_id,
#此种方法可以直接插入数据
models.User_NEW.objects.create(**all_data) #将方式2直接修改为此种方式创建数据
print models.User_NEW.objects.all().count()
else:
pass
user_list = models.User_NEW.objects.all() #数据查询
print user_list
return render(request,'foreign/create_user.html',{'obj':obj,'user_list':user_list})
app01/views/foreign.py
4、html模板文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/create_user/" method="post">
<p>{{ obj.username }}</p>
<p>{{ obj.user_group_id }}</p>
<input type="submit" value="submit"/>
</form>
<table>
{% for item in user_list %}
<tr>
<td>{{ item.username }}</td>
<td>{{ item.user_group.caption }}</td> {# 因为在model中的外键等一对多的操作,表示对象(就是一行数据),然后取一行数据的单独一列#}
</tr>
{% endfor %}
</table>
</body>
</html>
create_user.html
[<User_NEW: Charles>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: QQ>]
[/Jun/ ::] "GET /create_user/ HTTP/1.1"
数据提交
{'username': u'wahaha', 'user_group_id': } [<User_NEW: Charles>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: wahaha>]
[/Jun/ ::] "POST /create_user/ HTTP/1.1"
[<User_NEW: Charles>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: wahaha>]
[/Jun/ ::] "GET /create_user/ HTTP/1.1"
数据提交
{'username': u'aaa', 'user_group_id': } [<User_NEW: Charles>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: wahaha>, <User_NEW: aaa>]
[/Jun/ ::] "POST /create_user/ HTTP/1.1"
结果
通过get的方式获取想要查询的数据:
1、直接get获取数据库中的数据
def create_user(request):
obj = ForgienForm.UserForm(request.POST)
if request.method =="POST":
print "数据提交"
#print request.POST
if obj.is_valid():
all_data = obj.clean()
print all_data
#获取对象
# group_obj = models.UserGroup_NEW.objects.get(all_data['use_group']) 方式1 通过对象级别插入数据,group_obj代表对象,是一列数据
# models.User_NEW.objects.create(hostname=all_data['username'],
# user_group=group_obj)
# models.User_NEW.objects.create(hostname=all_data['username'],
# user_group_id=all_data['user_group']) #方式2:可以通过两种方式插入数据,默认在Django中插入外键会加_id,
#此种方法可以直接插入数据
models.User_NEW.objects.create(**all_data) #将方式2直接修改为此种方式创建数据
print models.User_NEW.objects.all().count()
else:
pass
val = request.GET.get('username') #通过get的方式获取数据
user_list = models.User_NEW.objects.filter(username=val) #数据查询
# user_list = models.User_NEW.objects.all() #数据查询
print user_list
return render(request,'foreign/create_user.html',{'obj':obj,'user_list':user_list})
app01/views/foreign.py
2、get通过对象获取数据
####通过双下划线实现
def create_user(request):
obj = ForgienForm.UserForm(request.POST)
if request.method =="POST":
print "数据提交"
#print request.POST
if obj.is_valid():
all_data = obj.clean()
print all_data
#获取对象
# group_obj = models.UserGroup_NEW.objects.get(all_data['use_group']) 方式1 通过对象级别插入数据,group_obj代表对象,是一列数据
# models.User_NEW.objects.create(hostname=all_data['username'],
# user_group=group_obj)
# models.User_NEW.objects.create(hostname=all_data['username'],
# user_group_id=all_data['user_group']) #方式2:可以通过两种方式插入数据,默认在Django中插入外键会加_id,
#此种方法可以直接插入数据
models.User_NEW.objects.create(**all_data) #将方式2直接修改为此种方式创建数据
print models.User_NEW.objects.all().count()
else:
pass
# val = request.GET.get('username') #通过get的方式获取数据
# user_list = models.User_NEW.objects.filter(username=val) #数据查询
# user_list = models.User_NEW.objects.all() #数据查询
val = request.GET.get('usergroup') #get获取对象的数据,通过__实现
user_list = models.User_NEW.objects.filter(user_group__caption=val)
print user_list
return render(request,'foreign/create_user.html',{'obj':obj,'user_list':user_list})
app01/views/foreign.py
注意:1、在连表操作的时候,ForeignKey对应的行表示对象;2、添加数据的时候,默认需要在对应的列的名称后面加_id;3、获取数据的时候,如果是使用模板语言,可以使用item.user_group.caption来获取另外一张表的数据;如果使用filter查询指定的数据,使用双下划线__来获得另外一张表对应的数据;
总结作业:
1、user_group对应对象;
2、创建数据 user_group_id;
3、获取数据 通过模板加.
4、查询数据 filter加__ 两个下划线表示跨一张表;
如果存在多张表通过外键进行关联:通过.filter(user_group__aa__name)进行数据查询
class A(models.Model):
name = models.CharField(max_length=) class UserGroup_NEW(models.Model):
caption = models.CharField(max_length=)
aa = models.ForeignKey('A')
def __unicode__(self):
return self.caption class User_NEW(models.Model):
username = models.CharField(max_length=)
user_group = models.ForeignKey('UserGroup_NEW') #默认创建的外键会加上_id,可以使用db_clomn来修改为自定义的列名
def __unicode__(self):
return self.username # .filter(user_group__aa__name)
多张表通过外键关联
后台也可以使用.连表来取数据:
for item in user_list:
print item.user_group.caption
作业:
xx管理:
、登录form
、session 结合装饰器
、装饰器
、主机、主机组进行关联;
添加:主机,主机组;
删除
修改
查
Django web 进阶的更多相关文章
- Python开发【第二十二篇】:Web框架之Django【进阶】
Python开发[第二十二篇]:Web框架之Django[进阶] 猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 ...
- Django 2.0 学习(07):Django 视图(进阶-续)
接Django 2.0 学习(06):Django 视图(进阶),我们将聚焦在使用简单的表单进行处理和精简代码. 编写简单表单 我们将用下面的代码,来替换之前的detail模板("polls ...
- Python之路【第十七篇】:Django【进阶篇 】
Python之路[第十七篇]:Django[进阶篇 ] Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接 ...
- Django web 开发指南 no such table:
在学习django web开发指南时,发布新博客点击save后会有error提示:no such table balabalabala... 百度了一下说重新运行manage.py syncdb 就可 ...
- Python之路【第十七篇】:Django【进阶篇】
Python之路[第十七篇]:Django[进阶篇 ] Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接 ...
- Python之路,Day15 - Django适当进阶篇
Python之路,Day15 - Django适当进阶篇 本节内容 学员管理系统练习 Django ORM操作进阶 用户认证 Django练习小项目:学员管理系统设计开发 带着项目需求学习是最有趣 ...
- django web 中添加超链接
django web 中添加不传参的超链接的方法如下: html: 在web中的超链接中加入一下url <a href="{% url 'app_name.views.url_func ...
- Python Django(WEB电商项目构建)
(坚持每一天,就是成功) Python Django Web框架,Django是一个开放源代码的Web应用框架,由Python写成.采用了MTV的框架模式,即模型M,模板T和视图V组成. 安装Pyth ...
- 教程:Visual Studio 中的 Django Web 框架入门
教程:Visual Studio 中的 Django Web 框架入门 Django 是高级 Python 框架,用于快速.安全及可扩展的 Web 开发. 本教程将在 Visual Studio 提供 ...
随机推荐
- HoloLens模拟器仿真器与文档现已向开发者们开放
HoloLens仿真器与文档现已向开发者们开放 直接上链接吧:http://mt.sohu.com/20160301/n438961462.shtml
- 浅谈mybatis中的#和$的区别
1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号.如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111&qu ...
- android的一些关键词
- 文章汇总(包括NVMe SPDK vSAN Ceph xfs等)
基础部分 NVMe驱动解析-前言 NVMe驱动解析-注册设备 NVMe驱动解析-关键的BAR空间 NVMe驱动解析-DMA传输(热门) NVMe驱动解析-响应I/O请求 用一个简单的例子窥探NVMe的 ...
- java对xml文件的读取
<?xml version="1.0" encoding="UTF-8"?> <body> <names type="1 ...
- 学习C++的第三天
1.sort函数(默认升序排序(从小到大)) 要使用此函数只需用#include <algorithm> sort即可使用,语法描述为: sort(begin,end),表示一个 ...
- jquery遍历数组与筛选数组的方法
grepgrep()方法用于数组元素过滤筛选 grep(array,callback,invert)array:待过滤数组;callback:处理数组中的每个元素,并过滤元素,该函数中包含两个参数,第 ...
- 【转】EXCEL不显示科学计数法
源地址:http://jingyan.baidu.com/article/e4d08ffdcc304e0fd3f60d69.html 2法无效,不知道为何
- ubuntu下编译protobuf
参考: http://blog.csdn.net/wuzuyu365/article/details/51900676 1.下载protobuf下载地址:https://github.com/goog ...
- (转载)FT232RL通信中断问题解决办法总结
原文地址:http://cuiweidabing.blog.163.com/blog/static/66631928201101514021658/ FT232RL是FTDI(www.ftdichip ...