安装django
pip3 install django
安装成功后在python的目录下的Scripts目录下生成了django-admin.exe
在windows命令行窗口执行django-admin.exe startproject mysite就会生成mysite文件夹
cd mysite
python manage.py runserver 程序可以工作了
创建Django工程
执行django-admin startproject mysite 【工程名称】
mysite - mysite # 对整个的程序进行配置 - init - settings # 配置文件 - url # URL对应关系 - wsgi # 遵循WSGI规范, uwsgi + nginx - manage.py # 管理Django程序
- python manage.py
- python manage.py startapp xx
- python manage.py makemigrations #
- python manage.py migrate #
运行Django功能
python manage.py runserver 127.0.0.1:8001
#urls.py from django.conf.urls import url from django.contrib import admin from django.shortcuts import HttpResponse import time def home(request): return HttpResponse('<h1>Hello</h1>') urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^h.html/', home), ]
chouti
- chouti
- 配置
- 主站 app
- 后台管理 app
创建app
python manage.py startapp cmdb
python manage.py startapp openstack
python manage.py startapp xxxxxx
app: migrations #数据修改表结构 admin #Django提供的后台管理 apps #配置当前app models #ORM,写指定的类,通过命令可以创建数据库结构 tests #单元测试 views #业务代码
1.配置模板的路径
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', ], }, }, ]
2.配置静态目录
static
STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), )
<link rel="stylesheet" href="/static/commons.css" />
写个登陆页面
#views.py from django.shortcuts import HttpResponse
from django.shortcuts import render
from django.shortcuts import redirect def login(request):
# 包含用户提交的所有信息
# 获取用户提交的方法
#print(request.method)
error_msg = ''
if request.method == "POST":
# 获取用户通过POST提交过来的数据
user=request.POST.get('user', None)
pwd=request.POST.get('pwd', None)
if user =='root' and pwd == '123':
return redirect('http://www.baidu.com')
else:
error_msg="用户名或密码错误"
return render(request,'login.html', {'error_msg': error_msg})
#urls.py from django.conf.urls import url from django.contrib import admin from cmdb import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login', views.login), ]
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/login/" method="POST" enctype="multipart/form-data"> <p> <input type="text" name="user" placeholder="用户名" /> </p> <p> <input type="password" name="pwd" placeholder="密码" /> </p> <p> 男:<input type="radio" name="gender" value="1"/> 女:<input type="radio" name="gender" value="2"/> </p> <p> 足球:<input type="checkbox" name="favor" value="11"/> 篮球:<input type="checkbox" name="favor" value="22"/> 乒乓球:<input type="checkbox" name="favor" value="33"/> </p> <p> <select name="city" multiple> <option value="sh">上海</option> <option value="bj">北京</option> <option value="tj">天津</option> </select> </p> <p> <input type="file" name="fafafa"> </p> <input type="submit" value="提交"/> </form> </body> </html>
定义视图函数
app下的views.py
def func(request): # request.method GET/POST # http://127.0.0.1:8009/home?nid=123&name=alex # request.GET.get('',name) # 获取请求发来的数据 # request.POST.get('',None) # return HttpResponse('字符串') # return render(request, "HTML模板的路径") # return redirect('/只能填URL')
for循环
def func(request): return render(request, "index.html", {'current_user':'tom','user_list': ['tom','eric']})
index.html
<html> .. <body> <div>{{current_user}}</div> <ul> {% for row in user_list %} {% if row == "tom" %} <li>{{ row }}</li> {% endfor %} {% endfor %} </ul> </body> </html>
条件
def func(request): return render(request, "index.html", { 'current_user':'tom', "age": 18, 'user_list': {'tom','jerry'}, 'user_dict': {'k1':'v1','k2':'v2'}})
index.html
<html> .. <body> <div>{{current_user}}</div> <a>{{user_list.1}}</a> <a>{{user_dict.k1}}</a> <a>{{user_dict.k2}}</a> {% if age %} <a>有年龄</a> {% if age > 16 %} <a>老男人</a> {% else %} <a>小鲜肉</a> {% endif %} {% else %} <a>无年龄</a> {% endif %} </body> </html>
Django请求生命周期
->URL对应关系->视图函数->返回用户字符串
->URL对应关系->视图函数->打开一个HTML文件,读取内容
创建django项目的基本准备
django-admin startproject mysite mysite mysite - 配置文件 - url.py - settings.py cd mysite python manage.py startapp cmdb mysite mysite - 配置文件 - url.py - settings.py cmdb - views.py - admin.py - models.py # 创建数据库表 3.配置 模板路径 静态文件路径 4.编写程序 a. urls.py /index/ -> func b. views.py def func(request): # 包含所有的请求数据 ... return HttpResponse('字符串') return render(request, 'index.html', {'':''}) return redirect('URL') c. 模板语言 return render(request, 'index.html', {'li': [11,22,33]}) {% for item in li %} <h1>{{item}}</h1> {% endfor %} ****索引****** <h2>{{item.0}}</h2>
路由系统
1.url(r'^index/', views.index), url(r'^home/', views.Home.as_view()), 2.url(r'^detail-(d+).html', views.detail), 3.url(r'^detail-(?P<nid>d+)-(?P<uid>d+).html', views.detail), 推荐
4.name
对URL路由关系进行命名,以后可以根据此名称生成自己想要的URL
url(r'^dsfdsfd/', views.index, name='i1')
url(r'^yug/(d+)(d+)', views.index, name='i2')
url(r'^buy/(?P<pid>d+)/(?P<nid>d+)/', views.index, name='i3')
def func(request, *args, **kwasrgs):
from django.urls import reverse
url1 = reverse('i1') # dsfdsfd
url2 = reverse('i2', args=(1,2,)) # yue/1/2/
url3 = reverse('i3', kwargs={'pid': 1, 'nid': 9}) # buy/1/9/
xxx.html
{% url 'i1' %} # dsfdsfd
(% url 'i2' 1 2 %) # yug/1/2/
{% url 'i3' pid=1 nid=9 %} # buy/1/9/
5.多级路由
#project/urls.py
from django.conf.urls import url,include
from django.contrib import admin
urlpatterns = [
url(r'^cmdb/', include("app01.urls")),
url(r'^monitor/', include("app02.urls")),
]
#app01/urls.py
from django.conf.urls import url,include
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^login/', views.login),
]
#app02/urls.py
from django.conf.urls import url,include
from django.contrib import admin
from app02 import views
urlpatterns = [
url(r'^login/', views.login),
]
6.默认值
7.命名空间
# http://www.cnblogs.com/wupeiqi/articles/5237704.html
实战: a. url(r'^detail-(d+)-(d+).html', views.detail), def func(request, nid, uid): pass def func(request, *args): args = (2,9) def func(request, *args, **kwargs): args = (2,9) b. url(r'^detail-(?P<nid>d+)-(?P<uid>d+).html', views.detail) def func(request, nid, uid): pass def func(request, *kwargs): kwargs = {'nid': 1, 'uid': 3} def func(request, *args, **kwargs): kwargs = {'nid': 1, 'uid': 3}
视图
#获取请求的三种方式 request.GET request.POST request.FILES
#checkbox等多选的内容 request.POST.getlist() #上传文件,for标签 enctype="multipart/form-data" obj = request.FILES.get('fafafa') import os filepath = os.path.join('upload', obj.name) f = open(filepath, 'wb') for i in obj.chunks(): f.write(i) f.close()
FBV & CBV
/index/ -> 函数名
/index/ -> 类
#home.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/home/" method="POST"> <input type="text"/> <input type="submit"/> </form> </body> </html> #urls.py urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/', views.index), url(r'^login/', views.login), url(r'^home/', views.Home.as_view()), ]
#views.py from django.views import View class Home(View): def dispatch(self, request, *args, **kwargs): # 调用父类中的dispatch print('before') result = super(Home, self).dispatch(request, *args, **kwargs) print('after') return result def get(self,request): print(request.method) return render(request, 'home.html') def post(self,request): print(request.method) return render(request, 'home.html')
模板
ORM操作
select * from tb where id > 1 # 对应关系 models.tb.objects.filter(id__gt=1) models.tb.objects.filter(id=1) models.tb.objects.filter(id__lt=1)
创建类
1.根据类自动创建数据库表
#app01/models.py from django.db import models class Userinfo(models.Model): #id列自增,主键 #用户名列,字符串类型,指定长度 username = models.CharField(max_length=32) username = models.CharField(max_length=64) >python manage.py makemigrations >python manage.py migrate
注:
Django默认使用MySQLdb模块 (python3无法使用) 链接MySQL
修改为pymysql,在project同名文件夹下的__init__文件中添加如下代码即可:
#project_name/__init__.py import pymysql pymysql.install_as_MySQLdb()
2.根据类对数据库表中的数据进行各种操作
#views.py from app01 import models def orm(request): #创建 models.UserInfo.objects.create( username='root', # 数据库中会增加这两条数据 password='123' ) 或 dic = {'username': 'tom','password': '666'} models.UserInfo.objects.create(**dic) 或 obj = models.UserInfo(username='root',password='123') obj.save() return HttpResponse('orm')
#查
#result = models.UserInfo.objects.all() #拿到表中的所有数据,是QuerySet类型
result = models.UserInfo.objects.filter(username='root') # 相当于where查询
for row in result:
print(row.id, row.username, row.password)
print(result)
#删除
models.UserInfo.objects.filter(id=4).delete()
#更新
models.UserInfo.objects.all().update(password=666)
models.UserInfo.objects.filter(id=3).update(password=69)
return HttpRersponse('orm')
#views.py def login(request): if request.method == "GET": return render(request, 'login.html') elif request.method == "POST": u = request.POST.get('user') p = request.POST.get('pwd') #obj = models.UserInfo.objects.filter(username=u,password=p).first() #print(obj) #count=models.UserInfo.objects.filter(username=u,password=p).count()
obj = models.UserInfo.objects.filter(username=u,password=p).first()
if obj:
return redirect('/index/')
else:
return render(request,'login.html')
else:
return redirect('/index/')
def user_info(request):
if request.method == "GET":
user_list = models.UserInfo.objects.all()
return render(request, 'user_info.html', {'user_list': user_list})
elif request.method == "POST":
u = request.POST.get('user')
p = request.POST.get('pwd')
models.UserInfo.objects.create()
return redirect('/cmdb/user_info/')
字段:
字符串类型
数字
时间
二进制
自增
字段参数:
null -->db是否可以为空 default -->默认值 primary_key -->主键 db_column -->列名 db_column='cp' db_index -->是否是普通索引 db_index=True unique -->是否是唯一索引 unique=True unique_for_date -->只对时间做索引 unique_for_month -->只对月份做索引 unique_for_year -->只对年份做索引 choices -->django admin中显示下拉框,避免连表查询 class UserInfo(models.Model): ... user_type_choice = ( (1, '超级用户'), # 把选项放到了内存中,而没有放入一个表里面 (2, '普通用户'), (3, '无'), ) user_type_id = models.IntergerField(choices=user_type_choice,default=1) #默认为超级用户 auto_now_add -->创建时自动生成时间 ctime = models.DateTimeField(auto_now_add=True, null=True) auto_now -->更新时自动更新为当前时间 uptime = models.DateTimeField(auto_now=True, null=True) #obj = UserGroup.objects.filter(id=1).update(caption='CEO') --->不会更新时间,Django不支持 #obj = UserGroup.objects.filter(id=1).first() --->会更新时间 #obj.caption = 'CEO' #obj.save() blank -->在django admin中是否可以为空 username = models.CharField(max_length=32,blank=True) verbose_name -->django admin显示字段中文 username = models.CharField(max_length=32,blank=True,verbose_name='用户名') editable -->django admin中是否可以被编辑 username = models.CharField(max_length=32,blank=True,verbose_name='用户名',editable=False) error_message -->错误信息 password = models.CharField(max_length=60,error_message={'required':'请输入密码'}) help_text -->django admin中显示提示 password = models.CharField(max_length=60,help_text='pwd') validators -->django form,自定义错误信息
外键操作
class UserGroup(models.Model): uid = models.AutoField(primary_key=True) caption = models.CharField(max_length=32, unique=True) ctime = models.DateTimeField(auto_now_add=True, null=True) uptime = models.DateTimeField(auto_now=True,null=True) class UserInfo(models.Model): #id列自增,主键 #用户名列,字符串类型,指定长度 #字符串,数字,时间,二进制 username = models.CharField(max_length=32,blank=True,verbose_name='用户名') password = models.CharField(max_length=60, help_text='pwd') email = models.CharField(max_length=60) test = models.EmailField(max_length=19,null=True,error_message={'invalid':'请输入密码'}) user_type_choice = ( (1, '超级用户'), # 把选项放到了内存中,而没有放入一个表里面 (2, '普通用户'), (3, '无'), ) user_type_id = models.IntergerField(choices=user_type_choice,default=1) # user_group_id 数字 user_group = models.ForeignKey("UserGroup",to_field='uid',default=1) # 代指的是对象 注: user_list = models.UserInfo.objects.all() for row in user_list: print(row.user_group_id) #代表数据库中真实存在的数据 print(row.user_group) #指的是对象,是UserGroup类的对象,对象中封装了很多值,取得话通过.uid等取值 print(row.user_group.uid) == row.user_group_id print(row.user_group.caption) print(row.user_group.uptime)
更新
#一对多 #user_list = models.UserInfo.objects.all() models.UserInfo.objects.create( username='root1', password='123', email='dsf', test=''dfd, user_group_id=1 # 比下面的方式好的原因在于,只进行一次数据库操作 ) models.UserInfo.objects.create( username='root1', password='123', email='dsf', test=''dfd, user_group_id=models.UserInfo.objects.filter(id=1).first() # 先查询,再创建,进行了两次数据库操作 )
根据类对数据库表中的数据进行各种操作
一对多 a.外键 b.对于这个外键默认生成数据库的时候应该是 外键字段_id c.根据 外键字段_id 进行创建数据,这样就省了一次数据查询 models.tb.object.create(name='root',user_group_id=1)
请求的生命周期
路由系统--->视图函数(获取模板+数据--->渲染)--->字符串返回给用户
1.路由系统
/index/ --------> 函数或类.as_view()
/detail/(d+) -------->函数(参数) 或 类.as_view() (参数)
/detail/(?P<nid>d+) -------->函数(参数)或 类.as_view() (参数)
/detail/ -------->include("app01.urls")
/detail/ name='a1' -------->include("app01.urls")
---视图中:reverse
---模板中:{% url "al" %}
2.视图函数
FBV:函数
def index(request, *args, **kwasrgs):
.....
CBV:类
class Home(views.View):
def get(self,request,*args,**kwasrgs):
......
#获取用户请求的数据
request.POST.get
request.GET.get
request.FILES.get
........getlist() 适用于多选情况,如checkbox
request.path_info 获取当前请求的URL
文件对象 = request.FILES.get()
文件对象.name
文件对象.size
文件对象.chunks() 分块儿取数据
#给用户返回数据
render(request,'模板文件的路径',{'k1': [1,2,3,4],'k2':{'name':'zhang','age':22}})
redirect('URL')
HttpResponse(字符串)
4.模板语言
render(request, "模板路径",{'模板语言':1234,'k1': {1,2,3,4}, "k2": {'name': 'zhang', 'age': 22}}) <html> <body> <h1>{{ obj }}</h1> <h1>{{ k1.3 }}</h1> <h1>{{ k2.name }}</h1> {% for i in k1 %} <p> {{ i }} </p> {% endfor %} {% for row in k2.keys %} {{ row }} {% endfor %} {% for row in k2.keys %} {{ row }} {% endfor %} {% for row in k2.values %} {{ row }} {% endfor %} {% for k,v in k2.items %} {{ k }} - {{ v }} {% endfor %} </body> </html>
5.ORM
a.创建类和字段 class User(models.Model): id = models.IntergerField() name = models.CharField(max_length=10) #字符长度 python manage.py makemigrations python manage.py migrate #settings注册APP b.操作 增 models.User.objects.create(name='tom',age=18) dic = {'name' : 'tom', 'age' : 20} models.User.objects.create(**dic) obj = models.User(name='tom',age=20) obj.save() 删 models.User.objects.filter(id=1).delete() 改 models.User.objects.filter(di__gt=1 ).update(name=''tom,age=22) dic = {'name' : 'tom', 'age' : 20} models.User.objects.filter(id__gt=1).update(**dic) 查 models.User.objects.filter(id=1,name='root') models.User.objects.filter(id__gt=1,name='root') models.User.objects.filter(id__lt=1) models.User.objects.filter(id__gte=1) models.User.objects.filter(id__lte=1) dic = {'name':'xx','age':'22'} models.User.objects.filter(**dic) v1 = models.Business.objects.all() # QuerySet,内部元素都是对象 v2 = models.Business.objects.all().values('id','caption') # QuerySet,内部元素都是字典 v3 = models.Business.objects.all().value_list('id','caption') # QuerySet,内部元素都是元组 # 获取到的一个对象,如果不存在就报错 models.Business.objects.get(id=1) models.Business.objects.filter(id=1).first() # 获取到的是对象 或 None 外键: v = models.Host.objects.filter(nid__gt=0) v[0].b.caption ------> 通过 . 进行跨表 外键: class UserType(models.Model): caption = models.CharField(max_length=32) # 1. 普通用户 # 2. VIP用户 # 3. 游客 class User(models.Model): age=models.IntergerField() name=models.CharField(max_length=10) # 字符长度 # user_type_id=models.intergerField() # user_type = models.ForeignKey("UserType",to_field='id') # 约束 # name age user_type_id # tom 20 2 # jerry 20 3 # peter 20 1
6
Ajax
$.ajax({ url: '/host', # 要提交到哪里 type: "POST", #以什么方式提交 data: {'k1':123, 'k2':"root"} # 要提交的数据 success: function(data){ # 发请求过去后,函数不会执行,等到服务端返回数据这个函数就会自动被触发 // data是服务器端返回的字符串 var obj = JSON.parse(data) ; //转化为json对象 ,执行JSON.parse()的前提是 形似列表或字典的数据结构 } 建议:永远让服务器端返回一个json处理过的字典 return HttpResponse(json.dumps(字典)) 在这里不能使用redirect(),render() })