18.5 Django模型
Django对各种数据库提供了很好的支持,包括:PostgreSQL、MySQL、SQLite、Oracle
5.1、数据库配置
1、安装mysql驱动
pip install mysqlclient #注意,支持py2的最后版本是1.3.9
2、修改HelloWarld\HelloWarld\settings.py文件
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', #或者使用mysql.connector.django
'NAME': 'test', #创建数据库名为啥此处就是啥
'USER': 'root',
'PASSWORD': '',
'HOST':'localhost',
'PORT':'3306',
}
} #注意:黑体部分基本抹去重写。与MySQL中对应数据库和用户的设置相同。Django根据这一设置,与MySQL中相应的数据库和用户连接起来
3、附注说明
C:\XAMPP\mysql\bin> ./mysql #进入MySQL数据库。
MariaDB [(none)]> use test; #使用数据库。注意封号
MariaDB [test]> show tables; #展示表
5.2、定义模型
1、定义模型。此处定义为appA
django-admin.py startapp appA #创建应用。应用名要和settings中的INSTALLED_APPS下新增的名字一样
-----------------------------------------------------------------------------
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'appA', #此处appA为新增,则创建的应用名也要为“appA”
)
2、修改HelloWarld\appA\models.py文件代码
# -*- coding: utf-8 -*-
from django.db import models
class Test(models.Model): #括号中的内容是固定的
name = models.CharField(max_length=20) #类名代表了数据库表名,且继承了models.Model
3、>HelloWorld命令行下执行
python manage.py migrate #创建表结构
python manage.py makemigrations appA #让Django知道我们在我们的模型有一些变更
python manage.py migrate appA #创建表结构
4、数据表创建完毕
5.3、数据库操作
1、修改HelloWarld\HelloWarld\urls.py文件:
from django.conf.urls import *
from . import view,testdb
urlpatterns = [
url(r'^hello$', view.hello),
url(r'^testdb$', testdb.testdb),
]
2、新建testdb.py文件。即为HelloWarld\HelloWarld\testdb.py
# -*- coding: utf-8 -*-
from django.http import HttpResponse
from appA.models import Test #注意“appA”的对应关系
def testdb(request): #数据库操作
test1 = Test(name='runoob')
test1.save()
return HttpResponse("<p>数据添加成功!</p>")
3、访问http://127.0.0.1:8009/testdb即可
4、数据操作。针对HelloWarld\HelloWarld\testdb.py文件进行
# -*- coding: utf-8 -*-
from django.http import HttpResponse
from TestModel.models import Test
def testdb(request): #数据库操作
response = "" #初始化
response1 = ""
list = Test.objects.all() #通过objects这个模型管理器的all()获得所有数据行,相当于SQL中的SELECT * FROM
response2 = Test.objects.filter(id=1) #filter相当于SQL中的WHERE,可设置条件过滤结果
response3 = Test.objects.get(id=1) #获取单个对象
Test.objects.order_by('name')[0:2] #限制返回的数据相当于SQL中的OFFSET 0 LIMIT 2;
Test.objects.order_by("id") #数据排序
Test.objects.filter(name="runoob").order_by("id") #上面的方法可以连锁使用
for var in list: #输出所有数据
response1 += var.name + " "
response = response1
return HttpResponse("<p>" + response + "</p>")
#修改其中一个id=1的name字段,再save,相当于SQL中的UPDATE
test1 = Test.objects.get(id=1)
test1.name = 'Google'
test1.save()
Test.objects.filter(id=1).update(name='Google') #另外一种方式
Test.objects.all().update(name='Google') #修改所有的列
return HttpResponse("<p>修改成功</p>")
#删除id=1的数据
test1 = Test.objects.get(id=1)
test1.delete()
Test.objects.filter(id=1).delete() #另外一种方式
Test.objects.all().delete() #删除所有数据
return HttpResponse("<p>删除成功</p>")
5、多对一
# -*- coding: utf-8 -*-
#多对一模拟代码段。在\HelloWorld\HelloWorld\testdb.py
from ceshi.models import Test,Blog
test1=Test.objects.create(name='alen') #和models下的类对应
test2=Test.objects.create(name='max') #多对一中的“一”
test3=Test.objects.create(name='carl')
blog1=Blog.objects.create(name='alen_blog1',test=test1) #多对一中的“多”
-----------------------------------------------------------------------------
# -*- coding: utf-8 -*-
#多对一测试代码段。在HelloWorld\ceshi\models.py
from django.db import models
class Test(models.Model): #括号中的内容是固定的
name = models.CharField(max_length=20)
def __unicode__(self):
return self.name
class Blog(models.Model): #多对一。即多个Blog对应一个Test
name=models.CharField(max_length=20)
test=models.ForeignKey(Test) #注意!必须是ForeignKey
def __unicode__(self):
return self.name
6、多对多
# -*- coding: utf-8 -*-
#多对多模拟代码段。在\HelloWorld\HelloWorld\testdb.py
from ceshi.models import Test,Blog
Test.objects.create(name='Alen')
Test.objects.create(name='Ben')
Test.objects.create(name='Carl')
Test.objects.create(name='Dev')
authors=Test.object.all() #将以上作者都加入到该变量中
b1=Book()
b1.name='python book'
b1.authors.add(authors[0]) #加入第一个作者
b1.authors.add(authors[1]) #加入第二个作者
b1.authors.remove(Alen) #删除第一个作者
b1.authors.all() #查询所有作者
-----------------------------------------------------------------------------
# -*- coding: utf-8 -*-
#多对多测试代码段。在HelloWorld\ceshi\models.py
from django.db import models
class Test(models.Model): #括号中的内容是固定的
name = models.CharField(max_length=20)
def __unicode__(self):
return self.name
class Book(models.Model): #多对多。即多个Book对应多个Test
name=models.CharField(max_length=20)
test=models.ManyToManyField(Test) #注意!必须是ManyToManyField
def __unicode__(self):
return self.name
18.6 Django表单
6.1、http请求的get方法
1、新建文件/HelloWorld/HelloWorld/search.py。代码如下:
# -*- coding: utf-8 -*-
from django.http import HttpResponse
from django.shortcuts import render_to_response
def search_form(request): #表单
return render_to_response('search_form.html')
def search(request): #接收请求数据
request.encoding='utf-8'
if 'q' in request.GET:
message = '你搜索的内容为: ' + request.GET['q']
else:
message = '你提交了空表单'
return HttpResponse(message)
2、新建文件/HelloWorld/templates/search_form.html。代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>搜索实例</title>
</head>
<body>
<form action="/search" method="get">
<input type="text" name="q">
<input type="submit" value="搜索">
</form>
</body>
</html>
3、修改/HelloWorld/HelloWorld/urls.py文件代码:
from django.conf.urls import url
from . import view,testdb,search
urlpatterns = [
url(r'^hello$', view.hello),
url(r'^testdb$', testdb.testdb),
url(r'^search-form$', search.search_form),
url(r'^search$', search.search),
]
4、先启动服务器,再在浏览器中输入地址:http://127.0.0.1:8009/search-form即可打开相关服务。
6.2、http请求的post方法
1、新建文件/HelloWorld/tmplate/post.html。代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>么么哒(memeda.com)</title>
</head>
<body>
<form action="/search-post" method="post">
{% csrf_token %}
<input type="text" name="q">
<input type="submit" value="Submit">
</form>
<p>{{ rlt }}</p> #表格处理结果预留位置
</body>
</html>
2、新建文件/HelloWorld/HelloWorld/search2.py。代码如下:
# -*- coding: utf-8 -*-
from django.shortcuts import render
from django.views.decorators import csrf
def search_post(request): #接收POST请求数据
ctx ={}
if request.POST:
ctx['rlt'] = request.POST['q']
return render(request, "post.html", ctx)
3、修改/HelloWorld/HelloWorld/urls.py文件代码:
from django.conf.urls import url
from . import view,testdb,search,search2
urlpatterns = [
url(r'^hello$', view.hello),
url(r'^testdb$', testdb.testdb),
url(r'^search-form$', search.search_form),
url(r'^search$', search.search),
url(r'^search-post$', search2.search_post),
]
4、先启动服务器,再在浏览器中输入地址:http://127.0.0.1:8009/search-post即可打开相关服务。
6.3、Request对象
HttpRequest对象包含当前请求URL的一些信息:
方法 | 解释 |
---|---|
path | 请求页面的全路径,不包括域名 |
method | 请求中使用的HTTP方法的字符串表示。全大写表示 |
GET | 包含所有HTTP GET参数的类字典对象 |
POST | 包含所有HTTP POST参数的类字典对象 |
REQUEST | 是POST和GET属性的集合体,先查找POST属性,再查找GET属性 |
COOKIES | 包含所有cookies的标准Python字典对象。Keys和values都是字符串 |
FILES | 包含所有上传文件的类字典对象 |
META | 包含所有可用HTTP头部信息的字 |
user | 是一个django.contrib.auth.models.User对象,代表当前登录的用户 |
session | 唯一可读写的属性,代表当前会话的字典对象 |
raw_post_data | 原始HTTP POST数据,未解析过。 高级处理时会有用处 |
Request对象也有一些有用的方法:
方法 | 解释 |
---|---|
__getitem__(key) | 返回GET/POST的键值,先取POST,后取GET。如果键不存在抛出KeyError |
has_key() | 检查request.GET or request.POST中是否包含参数指定的Key |
get_full_path() | 返回包含查询字符串的请求路径 |
is_secure() | 如果请求是安全的,返回True,就是说,发出的是HTTPS请求 |
6.4、QueryDict对象
QueryDict实现所有标准的词典方法。还包括一些特有的方法:
方法 | 解释 |
---|---|
__getitem__ | 如果Key对应多个Value,__getitem__()返回最后一个value |
__setitem__ | 设置参数指定key的value列表(一个Python list) |
get() | 如果key对应多个value,get()返回最后一个value |
update() | 参数可以是QueryDict,也可以是标准字典 |
items() | 使用单值逻辑的__getitem__(): |
values() | 使用单值逻辑的__getitem__(): |
QueryDict也有一些方法,如下表:
方法 | 解释 |
---|---|
copy() | 返回对象的拷贝,内部实现是用Python标准库的copy.deepcopy() |
getlist(key) | 返回和参数key对应的所有值,作为一个Python list返回 |
setlist(key,list_) | 设置key的值为list_ (unlike __setitem__()) |
appendlist(key,item) | 添加item到和key关联的内部list |
setlistdefault(key,list) | 和setdefault有一点不同,它接受list而不是单个value作为参数 |
lists() | 返回key的所有值,作为一个list |
urlencode() | 返回一个以查询字符串格式进行格式化后的字符串 |