URL配置(URLconf)就像Django所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表。css
基本格式:html
from django.conf.urls import url urlpatterns = [ url(正则表达式, views视图,参数,别名), ]
注意:前端
Django 2.0版本中的路由系统是下面的写法(官方文档):python
from django.urls import path,re_path urlpatterns = [ path('articles/2003/', views.special_case_2003), path('articles/<int:year>/', views.year_archive), path('articles/<int:year>/<int:month>/', views.month_archive), path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail), ]
基本配置git
from django.conf.urls import url from . import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), url(r'^articles/([0-9]{4})/$', views.year_archive), url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail), ]
注意事项ajax
补充说明正则表达式
# 是否开启URL访问地址后面不为/跳转至带有/的路径的配置项 APPEND_SLASH=True 默认就是True 若是在settings.py中设置了 APPEND_SLASH=False,此时咱们再请求 http://www.example.com/blog 时就会提示找不到页面。
上面的示例使用简单的正则表达式分组匹配(经过圆括号)来捕获URL中的值并以位置参数形式传递给视图。数据库
在更高级的用法中,可使用分组命名匹配的正则表达式组来捕获URL中的值并以关键字参数形式传递给视图。django
在Python的正则表达式中,分组命名正则表达式组的语法是(?P
from django.conf.urls import url from . import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive), url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive), url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail), ]
这个实现与前面的示例彻底相同,只有一个细微的差异:捕获的值做为关键字参数而不是位置参数传递给视图函数。
URLconf匹配的位置
URLconf 在请求的URL 上查找,将它当作一个普通的Python 字符串。不包括GET和POST参数以及域名。 例如,http://www.example.com/myapp/ 请求中,URLconf 将查找 /myapp/ 。 在http://www.example.com/myapp/?page=3 请求中,URLconf 仍将查找 /myapp/ 。 URLconf 不检查请求的方法。换句话讲,全部的请求方法 —— 同一个URL的POST、GET、HEAD等等 —— 都将路由到相同的函数。
捕获的参数永远都是字符串
每一个在URLconf中捕获的参数都做为一个普通的Python字符串传递给视图,不管正则表达式使用的是什么匹配方式。例如,下面这行URLconf 中:
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
传递到视图函数views.year_archive() 中的year参数永远是一个字符串类型。
视图函数中指定默认值
# urls.py中 from django.conf.urls import url from . import views urlpatterns = [ url(r'^blog/$', views.page), url(r'^blog/page(?P<num>[0-9]+)/$', views.page), ] # views.py中,能够为num指定默认值 def page(request, num="1"): pass
在上面的例子中,两个URL模式指向相同的view - views.page - 可是第一个模式并无从URL中捕获任何东西。
若是第一个模式匹配上了,page()函数将使用其默认参数num=“1”,若是第二个模式匹配,page()将使用正则表达式捕获到的num值。
include其余的URLconfs
from django.conf.urls import include, url urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^blog/', include('blog.urls')), # 能够包含其余app的URLconfs文件 ]
URLconfs 具备一个钩子,让你传递一个Python 字典做为额外的参数传递给视图函数。
django.conf.urls.url() 能够接收一个可选的第三个参数,它是一个字典,表示想要传递给视图函数的额外关键字参数。
from django.conf.urls import url from . import views urlpatterns = [ url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}), ]
在这个例子中,对于/blog/2005/请求,Django 将调用views.year_archive(request, year='2005', foo='bar')。
当传递额外参数的字典中的参数和URL中捕获值的命名关键字参数同名时,函数调用时将使用的是字典中的参数,而不是URL中捕获的参数。
我们简单来讲就是能够给咱们的URL匹配规则起个名字,一个URL匹配模式起一个名字。
这样咱们之后就不须要写死URL代码了,只须要经过名字来调用当前的URL。
举个简单的例子:
url(r'^home', views.home, name='home'), # 给个人url匹配模式起名为 home url(r'^index/(\d*)', views.index, name='index'), # 给个人url匹配模式起名为index
在模板里面能够这样引用:
{% url 'home' %}
在views函数中能够这样引用:
from django.urls import reverse reverse("index", args=("2018", ))
例子:
from django.conf.urls import url from . import views urlpatterns = [ # ... url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'), # ... ]
根据这里的设计,某一年nnnn对应的归档的URL是/articles/nnnn/。
你能够在模板的代码中使用下面的方法得到它们:
<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a> <ul> {% for yearvar in year_list %} <li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li> {% endfor %} </ul>
在Python 代码中,这样使用:
from django.urls import reverse from django.shortcuts import redirect def redirect_to_year(request): # ... year = 2006 # ... return redirect(reverse('news-year-archive', args=(year,)))
即便不一样的APP使用相同的URL名称,URL的命名空间模式也可让你惟一反转命名的URL。
命名分组 url(r'^pub/edit/(?P<pk>\d+)/$', views.publisher_edit,name='publisher_edit'), 模板中使用: {% url 'publisher'%} ——》/app01/publisher_list/ 命名分组 {% url 'publisher_edit' publisher.id %} {% url 'publisher_edit' pk=publisher.id %} 视图中使用: from django.urls import reverse reverse('publisher') 命名分组 reverse('publisher_edit',args=(2,)) reverse('publisher_edit',kwargs={'pk':5}) 指定namespace='app01' 反向解析的时候 给name前面加上namespace ——》 namespace:name
一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求而且返回Web响应。
Django使用请求和响应对象来经过系统传递状态。
当浏览器向服务端请求一个页面时,Django建立一个HttpRequest对象,该对象包含关于请求的元数据。而后,Django加载相应的视图,将这个HttpRequest对象做为第一个参数传递给视图函数。
每一个视图负责返回一个HttpResponse对象。
咱们以前写过的都是基于函数的view,就叫FBV。还能够把view写成基于类的。 function based view.
FBV版本
# FBV版添加班级 def add_class(request): if request.method == "POST": class_name = request.POST.get("class_name") models.Classes.objects.create(name=class_name) return redirect("/class_list/") return render(request, "add_class.html")
CBV版本
# CBV版添加班级 from django.views import View class AddClass(View): def get(self, request): return render(request, "add_class.html") def post(self, request): class_name = request.POST.get("class_name") models.Classes.objects.create(name=class_name) return redirect("/class_list/") 使用CBV时,urls.py中也作对应的修改: url(r'^add_class/$', views.AddClass.as_view()),
FBV: 正常使用 给函数上加装饰器
def wrapper(func): def inner(*args, **kwargs): start_time = time.time() ret = func(*args, **kwargs) end_time = time.time() print("used:", end_time-start_time) return ret return inner # FBV版添加班级 @wrapper def add_class(request): if request.method == "POST": class_name = request.POST.get("class_name") models.Classes.objects.create(name=class_name) return redirect("/class_list/") return render(request, "add_class.html")
使用装饰器装饰CBV
# CBV版添加班级 from django.views import View from django.utils.decorators import method_decorator class AddClass(View): @method_decorator(wrapper) def get(self, request): return render(request, "add_class.html") def post(self, request): class_name = request.POST.get("class_name") models.Classes.objects.create(name=class_name) return redirect("/class_list/")
装饰器的使用:
FBV: 正常使用 给函数上加装饰器 CBV: from django.utils.decorators import method_decorator 1. 加在方法上 @method_decorator(timer) def get(self, request): 2. 加在dispatch方法上 @method_decorator(timer) def dispatch(self, request, *args, **kwargs): 3. 加在类上 @method_decorator(timer,name='post') @method_decorator(timer,name='get') class AddPublisher(View):
CBV的流程
1. AddPublisher.as_view() ——》 view函数 2. 请求到来的时候 执行view函数 1. AddPublisher实例化 对象 ——》 self 2. self.request = request 3. 执行self.dispatch(request, *args, **kwargs) 1. 经过反射 获取到 get post 方法 ——>handler 2. handler() ——》 得到HttpResponse对象
- 直接用装饰器
(<app01.views.AddPublisher object at 0x0000023DE99E57B8>, <WSGIRequest: GET '/app01/pub/add/'>) <function AddPublisher.get at 0x0000023DE992ED08>
- 使用method_decorator
(<WSGIRequest: GET '/app01/pub/add/'>,) <function method_decorator.<locals>._dec.<locals>._wrapper.<locals>.bound_func at 0x0000023372154EA0>
请求相关的经常使用值
属性
属性: django将请求报文中的请求行、头部信息、内容主体封装成 HttpRequest 类中的属性。 除了特殊说明的以外,其余均为只读的。 0.HttpRequest.scheme 表示请求方案的字符串(一般为http或https) 1.HttpRequest.body 一个字符串,表明请求报文的主体。在处理非 HTTP 形式的报文时很是有用,例如:二进制图片、XML,Json等。 可是,若是要处理表单数据的时候,推荐仍是使用 HttpRequest.POST 。 另外,咱们还能够用 python 的类文件方法去操做它,详情参考 HttpRequest.read() 。 2.HttpRequest.path 一个字符串,表示请求的路径组件(不含域名)。 例如:"/music/bands/the_beatles/" 3.HttpRequest.method 一个字符串,表示请求使用的HTTP 方法。必须使用大写。 例如:"GET"、"POST" 4.HttpRequest.encoding 一个字符串,表示提交的数据的编码方式(若是为 None 则表示使用 DEFAULT_CHARSET 的设置,默认为 'utf-8')。 这个属性是可写的,你能够修改它来修改访问表单数据使用的编码。 接下来对属性的任何访问(例如从 GET 或 POST 中读取数据)将使用新的 encoding 值。 若是你知道表单数据的编码不是 DEFAULT_CHARSET ,则使用它。 5.HttpRequest.GET 一个相似于字典的对象,包含 HTTP GET 的全部参数。详情请参考 QueryDict 对象。 6.HttpRequest.POST 一个相似于字典的对象,若是请求中包含表单数据,则将这些数据封装成 QueryDict 对象。 POST 请求能够带有空的 POST 字典 —— 若是经过 HTTP POST 方法发送一个表单,可是表单中没有任何的数据,QueryDict 对象依然会被建立。 所以,不该该使用 if request.POST 来检查使用的是不是POST 方法;应该使用 if request.method == "POST" 另外:若是使用 POST 上传文件的话,文件信息将包含在 FILES 属性中。 7.HttpRequest.COOKIES 一个标准的Python 字典,包含全部的cookie。键和值都为字符串。 8.HttpRequest.FILES 一个相似于字典的对象,包含全部的上传文件信息。 FILES 中的每一个键为<input type="file" name="" /> 中的name,值则为对应的数据。 注意,FILES 只有在请求的方法为POST 且提交的<form> 带有enctype="multipart/form-data" 的状况下才会 包含数据。不然,FILES 将为一个空的相似于字典的对象。 9.HttpRequest.META 一个标准的Python 字典,包含全部的HTTP 首部。具体的头部信息取决于客户端和服务器,下面是一些示例: CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。 CONTENT_TYPE —— 请求的正文的MIME 类型。 HTTP_ACCEPT —— 响应可接收的Content-Type。 HTTP_ACCEPT_ENCODING —— 响应可接收的编码。 HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。 HTTP_HOST —— 客服端发送的HTTP Host 头部。 HTTP_REFERER —— Referring 页面。 HTTP_USER_AGENT —— 客户端的user-agent 字符串。 QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。 REMOTE_ADDR —— 客户端的IP 地址。 REMOTE_HOST —— 客户端的主机名。 REMOTE_USER —— 服务器认证后的用户。 REQUEST_METHOD —— 一个字符串,例如"GET" 或"POST"。 SERVER_NAME —— 服务器的主机名。 SERVER_PORT —— 服务器的端口(是一个字符串)。 从上面能够看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 以外,请求中的任何 HTTP 首部转换为 META 的键时, 都会将全部字母大写并将链接符替换为下划线最后加上 HTTP_ 前缀。 因此,一个叫作 X-Bender 的头部将转换成 META 中的 HTTP_X_BENDER 键。 10.HttpRequest.user 一个 AUTH_USER_MODEL 类型的对象,表示当前登陆的用户。 若是用户当前没有登陆,user 将设置为 django.contrib.auth.models.AnonymousUser 的一个实例。你能够经过 is_authenticated() 区分它们。 例如: if request.user.is_authenticated(): # Do something for logged-in users. else: # Do something for anonymous users. user 只有当Django 启用 AuthenticationMiddleware 中间件时才可用。 ------------------------------------------------------------------------------------- 匿名用户 class models.AnonymousUser django.contrib.auth.models.AnonymousUser 类实现了django.contrib.auth.models.User 接口,但具备下面几个不一样点: id 永远为None。 username 永远为空字符串。 get_username() 永远返回空字符串。 is_staff 和 is_superuser 永远为False。 is_active 永远为 False。 groups 和 user_permissions 永远为空。 is_anonymous() 返回True 而不是False。 is_authenticated() 返回False 而不是True。 set_password()、check_password()、save() 和delete() 引起 NotImplementedError。 New in Django 1.8: 新增 AnonymousUser.get_username() 以更好地模拟 django.contrib.auth.models.User。 11.HttpRequest.session 一个既可读又可写的相似于字典的对象,表示当前的会话。只有当Django 启用会话的支持时才可用。 完整的细节参见会话的文档。
上传文件示例
def upload(request): """ 保存上传文件前,数据须要存放在某个位置。默认当上传文件小于2.5M时,django会将上传文件的所有内容读进内存。从内存读取一次,写磁盘一次。 但当上传文件很大时,django会把上传文件写到临时文件中,而后存放到系统临时文件夹中。 :param request: :return: """ if request.method == "POST": # 从请求的FILES中获取上传文件的文件名,file为页面上type=files类型input的name属性值 filename = request.FILES["file"].name # 在项目目录下新建一个文件 with open(filename, "wb") as f: # 从上传的文件对象中一点一点读 for chunk in request.FILES["file"].chunks(): # 写入本地文件 f.write(chunk) return HttpResponse("上传OK") 页面: <body> <form action="" method="post" enctype="multipart/form-data"> {% csrf_token %} <input type="file" name="file"> <button type="submit">上传</button> </form> </body>
请求相关方法
1.HttpRequest.get_host() 根据从HTTP_X_FORWARDED_HOST(若是打开 USE_X_FORWARDED_HOST,默认为False)和 HTTP_HOST 头部信息返回请求的原始主机。 若是这两个头部没有提供相应的值,则使用SERVER_NAME 和SERVER_PORT,在PEP 3333 中有详细描述。 USE_X_FORWARDED_HOST:一个布尔值,用于指定是否优先使用 X-Forwarded-Host 首部,仅在代理设置了该首部的状况下,才能够被使用。 例如:"127.0.0.1:8000" 注意:当主机位于多个代理后面时,get_host() 方法将会失败。除非使用中间件重写代理的首部。 2.HttpRequest.get_full_path() 返回 path,若是能够将加上查询字符串。 例如:"/music/bands/the_beatles/?print=true" 3.HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None) 返回签名过的Cookie 对应的值,若是签名再也不合法则返回django.core.signing.BadSignature。 若是提供 default 参数,将不会引起异常并返回 default 的值。 可选参数salt 能够用来对安全密钥强力攻击提供额外的保护。max_age 参数用于检查Cookie 对应的时间戳以确保Cookie 的时间不会超过max_age 秒。 复制代码 >>> request.get_signed_cookie('name') 'Tony' >>> request.get_signed_cookie('name', salt='name-salt') 'Tony' # 假设在设置cookie的时候使用的是相同的salt >>> request.get_signed_cookie('non-existing-cookie') ... KeyError: 'non-existing-cookie' # 没有相应的键时触发异常 >>> request.get_signed_cookie('non-existing-cookie', False) False >>> request.get_signed_cookie('cookie-that-was-tampered-with') ... BadSignature: ... >>> request.get_signed_cookie('name', max_age=60) ... SignatureExpired: Signature age 1677.3839159 > 60 seconds >>> request.get_signed_cookie('name', False, max_age=60) False 复制代码 4.HttpRequest.is_secure() 若是请求时是安全的,则返回True;即请求通是过 HTTPS 发起的。 5.HttpRequest.is_ajax() 若是请求是经过XMLHttpRequest 发起的,则返回True,方法是检查 HTTP_X_REQUESTED_WITH 相应的首部是不是字符串'XMLHttpRequest'。 大部分现代的 JavaScript 库都会发送这个头部。若是你编写本身的 XMLHttpRequest 调用(在浏览器端),你必须手工设置这个值来让 is_ajax() 能够工做。 若是一个响应须要根据请求是不是经过AJAX 发起的,而且你正在使用某种形式的缓存例如Django 的 cache middleware, 你应该使用 vary_on_headers('HTTP_X_REQUESTED_WITH') 装饰你的视图以让响应可以正确地缓存。
注意:键值对的值是多个的时候,好比checkbox类型的input标签,select标签,须要用:
request.POST.getlist("hobby")
HttpResponse('字符串') render(request,'html文件名',{}) 完整的页面 redirect(地址) '/zz/' 'https://v3.bootcss.com/css/#forms' Location :'/zz/'
JSON
方法一: 后端: 在试图函数中,return HttpResponse(json.dunps(data)),将字典转化为字符串。 前端: 在浏览器得console里,JSON.parse('{"name":"ALEX"}'),就把字符串转换为对象了 方法二: from django.http import JsonResponse return sonResponse({'foo': 'bar'}),浏览器不用parse了。 方法三:(设置响应头得方式) def data_json(request): data = {'name': 'alex', 'age': 73} data_list = [1, 22, 34, ] ret = HttpResponse(json.dumps(data)) ret['Content-Type'] = 'application/json' # return ret # Content-Type: text/html; charset=utf-8 return JsonResponse(data_list, safe=False) # Content-Type: application/json
注意:
JsonResponse默认只能传递字典类型,若是要传递非字典类型须要设置一下safe关键字参数。
response = JsonResponse([1, 2, 3], safe=False)
Django模板中只须要记两种特殊符号: {{ }}和 {% %} {{ }}表示变量,在模板渲染的时候替换成值,{% %}表示逻辑相关的操做。
变量
view中代码:
def template_test(request): l = [11, 22, 33] d = {"name": "alex"} class Person(object): def __init__(self, name, age): self.name = name self.age = age def dream(self): return "{} is dream...".format(self.name) Alex = Person(name="Alex", age=34) Egon = Person(name="Egon", age=9000) Eva_J = Person(name="Eva_J", age=18) person_list = [Alex, Egon, Eva_J] return render(request, "template_test.html", {"l": l, "d": d, "person_list": person_list})
模板中支持的写法:
{# 取l中的第一个参数 #} {{ l.0 }} {# 取字典中key的值 #} {{ d.name }} {# 取对象的name属性 #} {{ person_list.0.name }} {# .操做只能调用不带参数的方法 #} {{ person_list.0.dream }}
注意:
注:当模板系统遇到一个(.)时,会按照以下的顺序去查询: 在字典中查询 属性或者方法 数字索引
Filters
翻译为过滤器,用来修改变量的显示结果。
语法: {{ value|filter_name:参数 }}
'|'左右没有空格没有空格没有空格
default
{{ value|default:"nothing"}} 若是value值没传的话就显示nothing
filesizeformat
将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如:
{{ value|filesizeformat }}
add
{{ value|add:"2" }} value是数字4,则输出结果为6。 {{ first|add:second }} 若是first是 [1,.2,3] ,second是 [4,5,6] ,那输出结果是 [1,2,3,4,5,6] 。
lower
小写 {{ value|lower }}
length
{{ value|length }} 返回value的长度,如 value=['a', 'b', 'c', 'd']的话,就显示4.
date
日期格式化 {{ value|date:"Y-m-d H:i:s"}} 全局的配置: 在settings里面写: DATATIME_FORMAT = 'Y-m-d H:i:s' USE_LION = False
safe
为了在Django中关闭HTML的自动转义有两种方式,若是是一个单独的变量咱们能够经过过滤器“|safe”的方式告诉Django这段代码是安全的没必要转义。
好比: value = "<a href='#'>点我</a>" {{ value|safe}}
for循环可用的一些参数:
Variable Description forloop.counter 当前循环的索引值(从1开始) forloop.counter0 当前循环的索引值(从0开始) forloop.revcounter 当前循环的倒序索引值(从1开始) forloop.revcounter0 当前循环的倒序索引值(从0开始) forloop.first 当前循环是否是第一次循环(布尔值) forloop.last 当前循环是否是最后一次循环(布尔值) forloop.parentloop 本层循环的外层循环 须要引用外出循环的一些参数时候
for ... empty
<ul> {% for user in user_list %} <li>{{ user.name }}</li> {% empty %} <li>空空如也</li> {% endfor %} </ul> 示例: {% empty %} <tr><td colspan='4' style='text-aline:center'>没有数据</td></tr>
csrf_token
这个标签用于跨站请求伪造保护。 在页面的form表单里面写上{% csrf_token %}
if,elif和else
{% if user_list %} 用户人数:{{ user_list|length }} {% elif black_list %} 黑名单数:{{ black_list|length }} {% else %} 没有用户 {% endif %} if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。
注意事项:
Django的模板语言不支持连续判断,即不支持如下写法:
{% if a > b > c %}
...
{% endif %}
继承母版
在子页面中在页面最上方使用下面的语法来继承母板。 {% extends 'layouts.html' %}
块(block)
经过在母板中使用{% block xxx %}来定义"块"。 在子页面中经过定义母板中的block名来对应替换母板中相应的内容。 {% block page-main %} <p>世情薄</p> <p>人情恶</p> <p>雨送黄昏花易落</p> {% endblock %}
组件
能够将经常使用的页面内容如导航条,页尾信息等组件保存在单独的文件中,而后在须要使用的地方按以下语法导入便可。 {% include 'navbar.html' %}
静态文件相关
- {% load static %} <link rel="stylesheet" href="{% static 'bootstrap-3.3.7/css/bootstrap.css' %}" <link rel="stylesheet" href="{% static 'css/dsb.css' %}">} <link rel="stylesheet" href="{% get_static_prefix %}bootstrap-3.3.7/css/bootstrap.css"> <link rel="stylesheet" href="{% get_static_prefix %}css/dsb.css">
经常使用字段
AutoField 自增的整形字段,必填参数primary_key=True,则成为数据库的主键。无该字段时,django自动建立。 一个model不能有两个AutoField字段。 IntegerField 一个整数类型。数值的范围是 -2147483648 ~ 2147483647。 CharField 字符类型,必须提供max_length参数。max_length表示字符的长度。 DateField 日期类型,日期格式为YYYY-MM-DD,至关于Python中的datetime.date的实例。 参数: auto_now:每次修改时修改成当前日期时间。 auto_now_add:新建立对象时自动添加当前日期时间。 auto_now和auto_now_add和default参数是互斥的,不能同时设置。 DatetimeField 日期时间字段,格式为YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],至关于Python中的datetime.datetime的实例。
字段类型
AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - bigint自增列,必须填入参数 primary_key=True 注:当model中若是没有自增列,则自动会建立一个列名为id的列 from django.db import models class UserInfo(models.Model): # 自动建立一个列名为id的且为自增的整数列 username = models.CharField(max_length=32) class Group(models.Model): # 自定义自增列 nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) SmallIntegerField(IntegerField): - 小整数 -32768 ~ 32767 PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) - 正小整数 0 ~ 32767 IntegerField(Field) - 整数列(有符号的) -2147483648 ~ 2147483647 PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) - 正整数 0 ~ 2147483647 BigIntegerField(IntegerField): - 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807 BooleanField(Field) - 布尔值类型 NullBooleanField(Field): - 能够为空的布尔值 CharField(Field) - 字符类型 - 必须提供max_length参数, max_length表示字符长度 TextField(Field) - 文本类型 EmailField(CharField): - 字符串类型,Django Admin以及ModelForm中提供验证机制 IPAddressField(Field) - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制 GenericIPAddressField(Field) - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6 - 参数: protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6" unpack_ipv4, 若是指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启此功能,须要protocol="both" URLField(CharField) - 字符串类型,Django Admin以及ModelForm中提供验证 URL SlugField(CharField) - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、链接符(减号) CommaSeparatedIntegerField(CharField) - 字符串类型,格式必须为逗号分割的数字 UUIDField(Field) - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证 FilePathField(Field) - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能 - 参数: path, 文件夹路径 match=None, 正则匹配 recursive=False, 递归下面的文件夹 allow_files=True, 容许文件 allow_folders=False, 容许文件夹 FileField(Field) - 字符串,路径保存在数据库,文件上传到指定目录 - 参数: upload_to = "" 上传文件的保存路径 storage = None 存储组件,默认django.core.files.storage.FileSystemStorage ImageField(FileField) - 字符串,路径保存在数据库,文件上传到指定目录 - 参数: upload_to = "" 上传文件的保存路径 storage = None 存储组件,默认django.core.files.storage.FileSystemStorage width_field=None, 上传图片的高度保存的数据库字段名(字符串) height_field=None 上传图片的宽度保存的数据库字段名(字符串) DateTimeField(DateField) - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] DateField(DateTimeCheckMixin, Field) - 日期格式 YYYY-MM-DD TimeField(DateTimeCheckMixin, Field) - 时间格式 HH:MM[:ss[.uuuuuu]] DurationField(Field) - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型 FloatField(Field) - 浮点型 DecimalField(Field) - 10进制小数 - 参数: max_digits,小数总长度 decimal_places,小数位长度 BinaryField(Field) - 二进制类型
字段参数
null 数据库中字段是否能够为空 db_column 数据库中字段的列名 default 数据库中字段的默认值 primary_key 数据库中字段是否为主键 db_index 数据库中字段是否能够创建索引 unique 数据库中字段是否能够创建惟一索引
Model Meta参数
class UserInfo(models.Model): nid = models.AutoField(primary_key=True) username = models.CharField(max_length=32) class Meta: # 数据库中生成的表名称 默认 app名称 + 下划线 + 类名 db_table = "table_name" # 联合索引 index_together = [ ("pub_date", "deadline"), # 应为两个存在的字段 ] # 联合惟一索引 unique_together = (("driver", "restaurant"),) # 应为两个存在的字段
import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") import django django.setup() from app01 import models # 获取对象 ret = models.User.objects.get(id=1) # 获取所全部 ——》 对象列表 ret = models.User.objects.all() # 获取全部知足条件的对象 ——》对象列表 ret = models.User.objects.filter() # 获取全部不知足条件的对象 ——》对象列表 ret = models.User.objects.exclude(id=1) # values ——》对象列表 {} # 不写参数 拿全部字段name 和 value # 写参数 拿指定字段name 和 value ret = models.User.objects.all().values('name','id') # values_list ——》对象列表 () # 不写参数 拿全部字段value # 写参数 拿指定字段value ret = models.User.objects.all().values_list('name','id') ret = models.User.objects.all().order_by('age','-id') ret = models.User.objects.all().order_by('id').reverse() # distinct() 去重 ret = models.User.objects.all().count() ret = models.User.objects.filter(id=100).exists() print(ret) """ 返回对象列表的方法 1. all() 2. filter() 3. exclude() 4. order_by() 5. reverse() 6. values() {} 7. values_list() () 8. distinct() 返回对象的 1. get() 2. first() 3. last() 返回布尔值 1. exists() 返回数字的 1. count() """
import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") import django django.setup() from app01 import models ret = models.User.objects.filter(id__gt=1) # greater than ret = models.User.objects.filter(id__gte=1) # greater than equal ret = models.User.objects.filter(id__lt=5) # less than ret = models.User.objects.filter(id__lte=3) # less than equal ret = models.User.objects.filter(id__in=[1,3,5]) ret = models.User.objects.filter(id__range=[1,3]) ret = models.User.objects.filter(name__contains='e') # ret = models.User.objects.filter(name__icontains='e') ret = models.User.objects.filter(name__startswith='h') ret = models.User.objects.filter(birth__year='2018') ret = models.User.objects.filter(birth__month='10') ret = models.User.objects.filter(birth__day='13') print(ret)
正向查找
对象查找(跨表)
语法: 对象.关联字段.字段 示例: book_obj = models.Book.objects.first() # 第一本书对象 print(book_obj.publisher) # 获得这本书关联的出版社对象 print(book_obj.publisher.name) # 获得出版社对象的名称
字段查找(跨表)
语法:
关联字段__字段 示例: print(models.Book.objects.values_list("publisher__name")) 回到顶部
反向操做
对象查找
语法: obj.表名_set 示例: publisher_obj = models.Publisher.objects.first() # 找到第一个出版社对象 books = publisher_obj.book_set.all() # 找到第一个出版社出版的全部书 titles = books.values_list("title") # 找到第一个出版社出版的全部书的书名
字段查找
语法: 表名__字段 示例: titles = models.Publisher.objects.values_list("book__title")
示例:
import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") import django django.setup() from app01 import models obj=models.Book.objects.get(id=1) print(obj.publisher) ret = models.Book.objects.filter(publisher__name='沙河出版社') # print(ret) pub_obj = models.Publisher.objects.get(id=14) print(pub_obj.book_set.all()) print(models.Publisher.objects.filter(book__title='九阳真经'))