Django

Django

安装

  • 安装:pip install django,默认安装在python 的 Scripts 目录下
  • 将Script添加至环境变量:如C:\D\program\Python354\Scripts
  • CMD中运行,创建Django工程:django-admin.exe startproject mysite(或者 django-admin startproject mysite) 创建工程mysite目录;mysite可以换成其他目录名
  • 在CMD中运行manage.py,启动Django功能:python manage.py runserver 127.0.0.1:8001

运行

  • 专业版pycharm:可以直接创建django项目,然后可以选择django项目运行
  • 非专业版pycharm:不能直接创建django项目,在run图标左侧,选择manage点击可看见Edit Configurations,点击后可看见Parameters,只需配置“runserver 127.0.0.1:8001”,然后保存即可运行manage.

 

project目录

  mysite
    - mysite        # 对整个程序进行配置
        - init
        - settings  # 配置文件
        - url       # URL对应关系
        - wsgi      # 遵循WSIG规范,uwsgi + nginx
    - manage.py     # 管理Django程序:

manage命令

manage.py runserver 0.0.0.0
python manage.py startapp appname
python manage.py syncdb
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser

APP 目录

创建app:python manage.py startapp app_name

migrations:     数据库操作记录,只记录修改表结构记录,不包括插入等
admin:          django提供的后台管理
apps:           配置当前app
models:        ORM,写指定的类,通过命令可以创建数据结构
tests:          单元测试
views:          业务代码  

配置

创建完project,做如下配置

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、配置静态目录,在setting文件最下面

   
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),)

<!-- 引用静态文件-->
<img class="logo left" src='/static/in.png' alt="Logo">
   

3、数据库

   
DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME':'dbname',
    'USER': 'root',
    'PASSWORD': 'xxx',
    'HOST': '',
    'PORT': '',
    }
}

# 由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替

# 如下设置放置的与project同名的配置的 __init__.py文件中
import pymysql
pymysql.install_as_MySQLdb()
   

MTV模式

  
Model:数据库,负责业务对象与数据库的对象(ORM)
Template: 模板文件,负责如何把页面展示给用户
View: 业务处理,负责业务逻辑,并在适当的时候调用Model和Template
urls分发器:将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template
  

实例

 1 from django.shortcuts import render
 2 from django.shortcuts import HttpResponse
 3 from django.shortcuts import render
 4 from django.shortcuts import redirect
 5 # Create your views here.
 6 
 7 user_list = [
 8     {'username':'a','email':'aaaaaa','gender':'M'},
 9     {'username':'b','email':'bbbbbb','gender':'M'},
10     {'username':'c','email':'cccccc','gender':'F'}
11 ]
12 
13 
14 def home(request):
15     if request.method == "POST":
16         u = request.POST.get('username')
17         e = request.POST.get('email')
18         g = request.POST.get('gender')
19         temp = {"username":u,"email":e,"gender":g}
20         user_list.append(temp)
21     return render(request,'home.html',{'user_list':user_list})
22 
23 def login(request):
24     # 'django.middleware.csrf.CsrfViewMiddleware' 在setting中需要注释掉这一项,否则提交表单时会出错
25     #第一种打开html文件方式
26     # f = open('templates/login.html','r',encoding='utf-8')
27     # data = f.read()
28     # f.close()
29     # return HttpResponse(data)
30 
31     # 第2种打开html文件方式: 注意在setting需要配置template路径DIRS,
32     # TEMPLATES = [
33     #     {
34     #         'BACKEND': 'django.template.backends.django.DjangoTemplates',
35     #         'DIRS': [os.path.join(BASE_DIR, 'templates')],
36     #     },
37     # ]
38     error_msg = ''
39     if request.method=="POST":
40         user = request.POST.get('user',None)
41         pwd = request.POST.get("password",None)
42         if user=='root' and pwd == '123':
43             #  跳转到百度
44             # return redirect('www.baidu.com')
45             return redirect('/home')
46         else:
47             # 用户密码不匹配
48             error_msg = 'user or password error'
49 
50 
51     return render(request, 'login.html',{'error_msg':error_msg})
views
 1 from django.contrib import admin
 2 from django.urls import path
 3 from django.shortcuts import HttpResponse
 4 
 5 from cmdb import views
 6 
 7 
 8 
 9 
10 urlpatterns = [
11     path('admin/', admin.site.urls),
12     path('login', views.login),
13     path('home', views.home),
14 ]
url
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="/static/comments.css"/>
    <title>Title</title>

    <style>
        label{
                width:80px;
                text-align:right;
                display:inline-block;
        }


    </style>
</head>
<body>
    <form action="/login" method="post">
        <p>
            <label for="username">用户名:</label>
            <input id="username" type="text" name="user" />
        </p>
        <p>
            <label for="password">密  码:</label>
            <input id="password" type="text" name="password" />
            <input type="submit" value="提交"/>
            <span style="color: red;">{{error_msg}}</span>
        </p>
    </form>
    <script src="/static/jquery-1.12.4.js"></script>
</body>
</html>
login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <form action="/home" method="post">
        <input type="text" name="username" />
        <input type="text" name="email" />
        <input type="text" name="gender" />
        <input type="submit" value="添加" />
    </form>
</div>


<div>

    <table>
        {% for row in user_list %}
            <tr>
                <td>{{row.username}}</td>
                <td>{{row.gender}}</td>
                <td>{{row.email}}</td>
            </tr>
        {% endfor %}
    </table>




</div>




</body>
</html>
home.html

注:

  • 'django.middleware.csrf.CsrfViewMiddleware' 在setting中需要注释掉这一项,否则提交表单时会出错
  • redirect('http://www.baidu.com')             重定向,只能填url;如果填本地url,则为/login,加斜杠
  • render(request, 'login.html',{'error_msg':error_msg})    返回HTML文件
  • <span style="color: red;">{{error_msg}}</span>           error_msg相当于一个变量
  • <form action="/login" method="post"> 和 path('login',views.login): login后面要一样,要不都为login/,要不都为login

 


路由系统

https://docs.djangoproject.com/en/1.11/topics/http/urls/

https://docs.djangoproject.com/en/2.0/topics/http/urls/

URL配置(URLconf)就像Django 所支撑网站的目录,是URL与视图函数之间的映射表。

语法

  
# Django 1.1
from django.conf.urls import url
urlpatterns = [
     url(正则表达式, views视图函数,参数,别名),
]

# Django 2.0
from django.urls import path
urlpatterns = [
    path(正则表达式, views视图函数,参数,别名),
 ]

# 正则表达式:     一个正则表达式字符串
# views视图函数:  一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
# 参数:          可选的要传递给视图函数的默认参数(字典形式)
# 别名:          一个可选的name参数
  

单一路由对应

  
from django.urls import path
from cmdb import views

urlpatterns = [
    path('teststate',views.testState),
]
  

基于正则的路由

  
path('^index/(\d*)', views.index),
path('^manage/(?P\w*)/(?P\d*)', views.manage),
  
# urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。
# 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
  

APPEND_SLASH配置

Django settings.py配置文件中默认没有 APPEND_SLASH 这个参数,但 Django 默认这个参数为 APPEND_SLASH = True。 其作用就是自动在网址结尾加 '/'

from django.conf.urls import url
from app01 import views

urlpatterns = [
        url(r'^blog/$', views.blog),
]
# 访问 http://www.example.com/blog 时,默认将网址自动转换为 http://www.example/com/blog/ 。
# 如果在settings.py中设置了 APPEND_SLASH=False,此时我们再请求 http://www.example.com/blog 时就会提示找不到页面。

分组命名匹配

使用分组命名匹配的正则表达式组来捕获URL中的值并以关键字参数形式传递给视图。

  
# 在Python的正则表达式中,分组命名正则表达式组的语法是(?P<name>pattern),
# name是组的名称
# pattern是要匹配的模式。
  
path('^manage/(?P\w*)/(?P\d*)', views.manage),
  

对于Django2.0以后,urls.py配置不同,如果使用正则匹配,需要导入re_path

from django.urls import path, re_path

urlpatterns = [
    path(r'admin/', admin.site.urls),
    re_path(r'test/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})', views.test),]

正则表达式分组匹配(通过圆括号)来捕获URL中的值并以位置参数形式传递给视图。

 
url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),

在views 函数中,应当注意形参

def testState(request, *args, **kwagrs):

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等等 —— 都将路由到相同的函数

捕获的参数是字符串

url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
# 传递到视图函数views.year_archive() 中的year 参数永远是一个字符串类型。

视图函数中指定默认值

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中捕获任何东西。
# 如果第一个模式匹配上了,page()函数将使用其默认参数num=“1”,如果第二个模式匹配,page()将使用正则表达式捕获到的num值。

添加额外的参数

django.conf.urls.url() 函数可以接收一个可选的第三个参数,它是一个字典,表示想要传递给视图函数的额外关键字参数。

path(r'^manage/(?P<name>\w*)', views.manage,{'id':333}),
# Django 将调用views.manage(request, name=string, id=333')。

路由映射设置名称

pathl(r'^home', views.home, name='home'),           # url匹配模式起名为 home
pathl(r'^index/(\d*)', views.index, name='index'),  # url匹配模式起名为index

设置名称后,通过如下方式调用:

# 模板中使用生成URL     {% url 'index' 2012 %} 固定URL:2012 或 {{request.path_info}}  提交表单后返回当前url路径
# 函数中使用生成URL     reverse('index', args=(2012,))      路径:django.urls.reverse
# Model中使用获取URL   自定义get_absolute_url() 方法

class NewType(models.Model):
    caption = models.CharField(max_length=16)


    def get_absolute_url(self):
        """
        为每个对象生成一个URL
        应用:在对象列表中生成查看详细的URL,使用此方法即可!!!
        :return:
        """
        # return '/%s/%s' % (self._meta.db_table, self.id)
        #
        from django.urls import reverse
        return reverse('NewType.Detail', kwargs={'nid': self.id})   # 使用获取URL   自定义get_absolute_url() 方法

生成路径:

url(r'^test1',views.test, name='t1')
url(r'^test2/(\d+)/(\d+)/',views.test, name='t2')
url(r'^test3/(?P(pid)\d+)/(?P(nid)\d+)/',views.test, name='t3')

def func(request, *args, **kwargs):
    from django.urls import reverse
    
    url1 = reverse('t1')                              # test1/
    url2 = reverse('t2', args=(1,2,))           # test2/1/2/
    url3 = reverse('t3', kwagrs=('pid':1, 'nid':2))    # test3/1/2/

# html
#  {% url 't1' %}
#  {% url 't2' 1,2 %}
#  {% url 't3'  pid=1 nid=2%}

获取请求匹配成功的URL信息: request.resolver_match

对路由进行分类

根据app对路由规则进行分类

url(r'^web/',include('web.urls')),
# 可以包含其他的URLconfs文件

命名空间

即使不同的APP使用相同的URL名称,URL的命名空间模式也可以让你唯一反转命名的URL。

# project中的urls.py
from django.conf.urls import url, include
 
urlpatterns = [
    url(r'^app01/', include('app01.urls', namespace='app01')),
    url(r'^app02/', include('app02.urls', namespace='app02')),
]

# app01中的urls.py
from django.conf.urls import url
from app01 import views
 
app_name = 'app01'
urlpatterns = [
    url(r'^(?P<pk>\d+)/$', views.detail, name='detail')
]

# app02中的urls.py
from django.conf.urls import url
from app02 import views

app_name = 'app02'
urlpatterns = [
    url(r'^(?P<pk>\d+)/$', views.detail, name='detail')
]

以上定义带命名空间的url之后,使用name生成URL时候,应该如下:

# 模板中使用:
{% url 'app01:detail' pk=12 %}

# views中的函数中使用
v = reverse('app01:detail', kwargs={'pk':11})

 


视图

  
request.GET
request.POST
request.FILES
return HttpResponse("字符串")
return render(request, "HTML模板的路径")
return redirect('/只能填URL')
  

获取单选框内容

获取input radio 等单选的内容:

request.POST.get("radio_name")

获取复选框内容

获取checkbox等多选的内容,内容为一个列表:

request.POST.getlist('checkbox_name')

上传文件

上传文件,form标签做特殊设置:加上属性enctype="multipart/form-data",如果不加这项属性,默认发的不是文件,则request.FILES.get()为None.

obj = request.FILES.get()
obj.name
f = open(obj.name, 'wb')
for item in obj.chunks():
  f.write(item)
f.close

实例

views:

def login(request):
    if request.method == "GET":
        return render(request, 'login.html')
    elif request.method == "POST": 
        v = request.POST.get('gender') 
v
= request.POST.getlist('favor')
obj
= request.FILES.get('fa') print(obj,type(obj),obj.name) import os file_path = os.path.join('upload', obj.name) f = open(file_path, mode="wb") for i in obj.chunks(): f.write(i) f.close() return render(request, 'login.html') else: return redirect('/index/')

HTML

<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"/>
        </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="fa"/>
        </p>
        <input type="submit" value="提交"/>
    </form>

FBV

FBV:function base view

url.py:    index  => 函数名
view.py:   def  函数(request)

CBV

CBV:class base view

url.py:  index => 类
匹配到url后,先调用dispatch方法,再判断get or post继续执行

views:接收到请求后,会先调用dispach方法

from django.views import View

class Home(View):
    def dispatch(self, request, *args, **kwargs):
        result = super(Home,self).dispatch(request, *args, **kwargs)
        return result

    def get(self,request):
        return render(request,'home.html')

    def post(self,request):
        return render(request, 'home.html')

url:

from cmdb import views

urlpatterns = [
    path('home', views.Home.as_view()),
]

 


模板

https://docs.djangoproject.com/en/1.11/ref/templates/builtins/#std:templatetag-for

两个符号

<!--   {{}}:   变量相关     -->
<!--   {% %}:  逻辑相关     -->

变量

  
1、在Django的模板语言中按此语法使用:{{ 变量名 }}。
2、当模版引擎遇到一个变量,它将计算这个变量,然后用结果替换掉它本身。
3、变量的命名包括任何字母数字以及下划线 ("_")的组合。 变量名称中不能有空格或标点符号。
4、点(.)在模板语言中有特殊的含义。当模版系统遇到点("."),它将以这样的顺序查询:
     字典查询
     属性或方法查询
     数字索引查询

1、如果计算结果的值是可调用的,它将被无参数的调用。 调用的结果将成为模版的值。
2、如果使用的变量不存在, 模版系统将插入 string_if_invalid 选项的值, 它被默认设置为'' (空字符串) 。

实例

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})
view
 1 <body>
 2     <!--{# 取l中的第一个参数 #}-->
 3     {{ l.0 }}
 4     <br />
 5     {# 取字典中key的值 #}
 6     {{ d.name }}
 7     <br />
 8     {# 取对象的name属性 #}
 9     {{ person_list.0.name }}
10     <br />
11     {# .操作只能调用不带参数的方法 #}
12     {{ person_list.0.dream }}
13 </body>
template.html

Filters:过滤器

在Django的模板语言中,通过使用过滤器来改变变量的显示。

语法:使用管道符"|"来应用过滤器。

  
# {{ value|filter_name:参数 }}

{{ name|lower }}
# 会将name变量应用lower过滤器之后再显示它的值。lower在这里的作用是将文本全都变成小写。

注意

  • 过滤器支持“链式”操作。即一个过滤器的输出作为另一个过滤器的输入。
  • 过滤器可以接受参数,例如:{{ sss|truncatewords:30 }},这将显示sss的前30个词。
  • 过滤器参数包含空格的话,必须用引号包裹起来。比如使用逗号和空格去连接一个列表中的元素,如:{{ list|join:', ' }}
  • '|'左右没有空格没有空格没有空格

Django内置过滤器

default

# 如果一个变量是false或者为空,使用给定的默认值。 否则,使用变量的值。
{{ value|default:"nothing"}}

length

# 返回值的长度,作用于字符串和列表。
{{ value|length }}
# 返回value的长度,如 value=['a', 'b', 'c', 'd']的话,就显示4.

filesizeformat

# 将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。
{{ value|filesizeformat }}
# 如果 value 是 123456789,输出将会是 117.7 MB。

slice

# 切片
{{value|slice:"2:-1"}}

date

# 格式化时间
{{ value|date:"Y-m-d H:i:s"}}

truncatechars

# 如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。
# 参数:截断的字符数
{{ value|truncatechars:9}}

truncatewords

# 在一定数量的字后截断字符串。
{{ value|truncatewords:9}}

cut

# 移除value中所有的与给出的变量相同的字符串
{{ value|cut:' ' }}
# 如果value为'i love you',那么将输出'iloveyou'.

join

# 使用字符串连接列表,例如Python的str.join(list)

自定义filter

自定义过滤器只是带有一个或两个参数的Python函数:

# 变量(输入)的值 - -不一定是一个字符串
# 参数的值 - 这可以有一个默认值,或完全省略
# 例如,在过滤器{{var | foo:'bar'}}中,过滤器foo将传递变量var和参数“bar”。

在哪定义filter代码:

  
app01/
    __init__.py
    models.py
    templatetags/         # 在app01下面新建一个package package
        __init__.py
        app01_filters.py  # 建一个存放自定义filter的文件
    views.py
  

如何编写自定义filter

  
from django import template
register = template.Library()

@register.filter(name="say_hello")
def say_hello(value):
    return "hello {}".format(value)
  

如何使用自定义filter

  
{# 先导入我们自定义filter那个文件 #}
{% load app01_filters %}

{# 使用我们自定义的filter #}
{{ d.name|say_hello }}
  

for循环

<ul>
{% for user in user_list %}
    <li>{{ user.name }}</li>
{% endfor %}
</ul>

for ... empty

<ul>
{% for user in user_list %}
    <li>{{ user.name }}</li>
{% empty %}
    <li>空空如也</li>
{% endfor %}
</ul>

for语句在模板里的应用

for循环与table结合使用:在html中获取字典或列表里面的值,可以通过row.key或row.1等方式获得

# views代码
user_list = [
{'username':'a','email':'aaaaaa','gender':'M'},
{'username':'b','email':'bbbbbb','gender':'M'},
{'username':'c','email':'cccccc','gender':'F'}
]

return render(request,'home.html',{'user_list':user_list})

# HTML
<table>
{% for row in user_list %}
<tr>
<td>{{row.username}}</td>
<td>{{row.gender}}</td>
<td>{{row.email}}</td>
</tr>
{% endfor %}
</table>

模板语言访问字典

USER_DICT = {
'1': {'name': 'root1', 'email': 'root@live.com'},
'2': {'name': 'root2', 'email': 'root@live.com'},
}

# HTML
{{user_dict.k1}}

{%for k,v in user_dict.items%}
<li><{{k}}-{{v}}/li>
{%endfor%}

{%for k in user_dict.keys%}
<li><{{k}}/li>
{%endfor%}

{%for v in user_dict.values%}
<li><{{v}}/li>
{%endfor%}

条件判断

if ... else/ 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判断。

with

定义一个中间变量,多用于给一个复杂的变量起别名。

{% with total=business.employees.count %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}

{% with business.employees.count as total %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}

注:  等号左右不要加空格。

注释

{# ... #}

模板语言注意事项

  
1. Django的模板语言不支持连续判断,即不支持以下写法
    {% if a > b > c %}
        ...
    {% endif  }   %

2. Django的模板语言中属性的优先级大于方法
    def xx(request):
        d = {"a": 1, "b": 2, "c": 3, "items": "100"}
        return render(request, "xx.html", {"data": d})
如上,我们在使用render方法渲染一个页面的时候,传的字典d有一个key是items并且还有默认的 d.items() 方法,此时在模板语言中: {{ data.items }}{{ data.items }},默认会取d的items key的值。
  

 


ORM操作

对象关系映射(Object Relational Mapping,简称ORM)模式通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。

ORM在业务逻辑层和数据库层之间充当了桥梁的作用。

Django中ORM的配置

https://docs.djangoproject.com/en/2.0/topics/db/queries/

setting.py文件配置:

  
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.mysql",
        "NAME": "你的数据库名称",  # 需要自己手动创建数据库
        "USER": "数据库用户名",
        "PASSWORD": "数据库密码",
        "HOST": "数据库IP",
        "POST": 3306
    }
}
  

Django项目的__init__.py文件配置:

  
# 由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替
# 如下设置放置的与project同名的配置的 __init__.py文件中
import pymysql

pymysql.install_as_MySQLdb()
  

字段

  
AutoField:     int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。
IntegerField:  一个整数类型,范围在 -2147483648 to 2147483647。
CharField:     字符类型,必须提供max_length参数, max_length表示字符长度。
DateField:     日期字段,日期格式  YYYY-MM-DD,相当于Python中的datetime.date()实例。
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

    自定义无符号整数字段

        class UnsignedIntegerField(models.IntegerField):
            def db_type(self, connection):
                return 'integer UNSIGNED'

        PS: 返回值为字段在数据库中的属性,Django字段默认的值为:
            'AutoField': 'integer AUTO_INCREMENT',
            'BigAutoField': 'bigint AUTO_INCREMENT',
            'BinaryField': 'longblob',
            'BooleanField': 'bool',
            'CharField': 'varchar(%(max_length)s)',
            'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
            'DateField': 'date',
            'DateTimeField': 'datetime',
            'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
            'DurationField': 'bigint',
            'FileField': 'varchar(%(max_length)s)',
            'FilePathField': 'varchar(%(max_length)s)',
            'FloatField': 'double precision',
            'IntegerField': 'integer',
            'BigIntegerField': 'bigint',
            'IPAddressField': 'char(15)',
            'GenericIPAddressField': 'char(39)',
            'NullBooleanField': 'bool',
            'OneToOneField': 'integer',
            'PositiveIntegerField': 'integer UNSIGNED',
            'PositiveSmallIntegerField': 'smallint UNSIGNED',
            'SlugField': 'varchar(%(max_length)s)',
            'SmallIntegerField': 'smallint',
            'TextField': 'longtext',
            'TimeField': 'time',
            'UUIDField': 'char(32)',

    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      用于表示某个字段可以为空。
unique    如果设置为unique=True 则该字段在此表中必须是唯一的 。
db_index  如果db_index=True 则代表着为此字段设置数据库索引。
default   为该字段设置默认值。
  

其他参数:

null                数据库中字段是否可以为空
    db_column           数据库中字段的列名
    db_tablespace
    default             数据库中字段的默认值
    primary_key         数据库中字段是否为主键
    db_index            数据库中字段是否可以建立索引
    unique              数据库中字段是否可以建立唯一索引
    unique_for_date     数据库中字段【日期】部分是否可以建立唯一索引
    unique_for_month    数据库中字段【月】部分是否可以建立唯一索引
    unique_for_year     数据库中字段【年】部分是否可以建立唯一索引

    verbose_name        Admin中显示的字段名称
    blank               Admin中是否允许用户输入为空
    editable            Admin中是否可以编辑
    help_text           Admin中该字段的提示信息
    choices             Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
                        如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)

    error_messages      自定义错误信息(字典类型),从而定制想要显示的错误信息;
                        字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
                        如:{'null': "不能为空.", 'invalid': '格式错误'}

    validators          自定义错误验证(列表类型),从而定制想要的验证规则
                        from django.core.validators import RegexValidator
                        from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\
                        MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
                        如:
                            test = models.CharField(
                                max_length=32,
                                error_messages={
                                    'c1': '优先错信息1',
                                    'c2': '优先错信息2',
                                    'c3': '优先错信息3',
                                },
                                validators=[
                                    RegexValidator(regex='root_\d+', message='错误了', code='c1'),
                                    RegexValidator(regex='root_112233\d+', message='又错误了', code='c2'),
                                    EmailValidator(message='又错误了', code='c3'), ]
                            )
参数

元信息

  
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"),)

            # admin中显示的表名称
            verbose_name

            # verbose_name加s
            verbose_name_plural

拓展

1.触发Model中的验证和错误提示有两种方式:
        a. Django Admin中的错误信息会优先根据Admiin内部的ModelForm错误信息提示,如果都成功,才来检查Model的字段并显示指定错误信息
        b. 调用Model对象的 clean_fields 方法,如:
            # models.py
            class UserInfo(models.Model):
                nid = models.AutoField(primary_key=True)
                username = models.CharField(max_length=32)

                email = models.EmailField(error_messages={'invalid': '格式错了.'})

            # views.py
            def index(request):
                obj = models.UserInfo(username='11234', email='uu')
                try:
                    print(obj.clean_fields())
                except Exception as e:
                    print(e)
                return HttpResponse('ok')

           # Model的clean方法是一个钩子,可用于定制操作,如:上述的异常处理。

    2.Admin中修改错误提示
        # admin.py
        from django.contrib import admin
        from model_club import models
        from django import forms


        class UserInfoForm(forms.ModelForm):
            username = forms.CharField(error_messages={'required': '用户名不能为空.'})
            email = forms.EmailField(error_messages={'invalid': '邮箱格式错误.'})
            age = forms.IntegerField(initial=1, error_messages={'required': '请输入数值.', 'invalid': '年龄必须为数值.'})

            class Meta:
                model = models.UserInfo
                # fields = ('username',)
                fields = "__all__"


        class UserInfoAdmin(admin.ModelAdmin):
            form = UserInfoForm


        admin.site.register(models.UserInfo, UserInfoAdmin)
拓展
对应关系:
    'AutoField': 'integer AUTO_INCREMENT',
    'BigAutoField': 'bigint AUTO_INCREMENT',
    'BinaryField': 'longblob',
    'BooleanField': 'bool',
    'CharField': 'varchar(%(max_length)s)',
    'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
    'DateField': 'date',
    'DateTimeField': 'datetime',
    'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
    'DurationField': 'bigint',
    'FileField': 'varchar(%(max_length)s)',
    'FilePathField': 'varchar(%(max_length)s)',
    'FloatField': 'double precision',
    'IntegerField': 'integer',
    'BigIntegerField': 'bigint',
    'IPAddressField': 'char(15)',
    'GenericIPAddressField': 'char(39)',
    'NullBooleanField': 'bool',
    'OneToOneField': 'integer',
    'PositiveIntegerField': 'integer UNSIGNED',
    'PositiveSmallIntegerField': 'smallint UNSIGNED',
    'SlugField': 'varchar(%(max_length)s)',
    'SmallIntegerField': 'smallint',
    'TextField': 'longtext',
    'TimeField': 'time',
    'UUIDField': 'char(32)',
字段对应

时间字段

  
DatetimeField、DateField、TimeField   这个三个时间字段,都可以设置如下属性。
auto_now_add  配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。
auto_now      配置上auto_now=True,每次更新数据记录的时候会更新该字段。
1. 下面方式修改数据auto_now不生效
# obj = UserGroup.objects.filter(id=1).update(caption='CEO')
2. 使auto_now生效使用如下:
# obj = UserGroup.objects.filter(id=1).first()
# obj.caption = "CEO"
# obj.save()
  

连表结构

  
一对多:models.ForeignKey(其他表)
      user_group=models.ForeignKey('UserGroup',to_field='uid',default=1)   关联UserGroup表的uid字段
      创建用户:
        models.UserInfo.objects.create(user_group=models.UserGroup.objects.filter(id=1).frist())
       或: models.UserInfo.objects.create(user_group_id=1)
      外键查找关联表数据:
        uid=models.UserInfo.objects.filter(id=1).first().user_group_id        查找组id
        user_group=models.UserInfo.objects.filter(id=1).first().user_group         返回一个UserGroup对象,可查找UserGroup表的所有信息 
多对多:models.ManyToManyField(其他表)
一对一:models.OneToOneField(其他表)
  

表的基本操作

  
# 增    # models.Tb1.objects.create(c1='xx', c2='oo')  增加一条数据,可以接受字典类型数据 **kwargs
    # obj = models.Tb1(c1='xx', c2='oo')
    # obj.save()
# 查    # models.Tb1.objects.get(id=123)         # 获取单条数据,不存在则报错(不建议)
    # data= models.Tb1.objects.all()             # 获取全部数据,QuerySet类型,[obj1,obj2....]
    data.query()                  # 将查询语句翻译成SQL查询语句 select * from tb # models.Tb1.objects.filter(name='seven') # 获取指定条件的数据 # models.Tb1.objects.all().values('字段1','字段2'...) # 获取全部数据,返回QuerySet类型[{'字段1':value,'字段2':value},{},{}] # models.Tb1.objects.all().values_list('字段1','字段2'..) # 获取全部数据,返回QuerySet类型[(value1,value2..),()...] # 删 # models.Tb1.objects.filter(name='seven').delete() # 删除指定条件的数据 # 改 # models.Tb1.objects.filter(name='seven').update(gender='0') # 将指定条件的数据更新,均支持 **kwargs # obj = models.Tb1.objects.get(id=1) # obj.c1 = '111' # obj.save() # 修改单条数据   

操作表常用属性

  
all():                 查询所有结果
filter(**kwargs):      它包含了与所给筛选条件相匹配的对象
get(**kwargs):         返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
exclude(**kwargs):     它包含了与所给筛选条件不匹配的对象
values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列
values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
order_by(*field):      对查询结果排序
reverse():             对查询结果反向排序,请注意reverse()通常只能在具有已定义顺序的QuerySet上调用(在model类的Meta中指定ordering或调用order_by()方法)。
distinct():            从返回结果中剔除重复纪录(如果你查询跨越多个表,可能在计算QuerySet时得到重复的结果。此时可以使用distinct(),注意只有在PostgreSQL中支持按字段去重。)
count():              返回数据库中匹配查询(QuerySet)的对象数量。
first():              返回第一条记录,若没有则为None。可以和filter结合起来使用
last():               返回最后一条记录
exists():             如果QuerySet包含数据,就返回True,否则返回False
  

参考:

https://www.cnblogs.com/liwenzhou/p/9959979.html

 


posted @ 2018-12-23 22:32  徘徊的游鱼  阅读(719)  评论(0编辑  收藏  举报