Django框架全面讲解

转:https://www.cnblogs.com/LiCheng-/p/6920900.html

Django框架全面讲解

Python的WEB框架有Django、Tornado、Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM、模型绑定、模板引擎、缓存、Session等诸多功能。

本文将以下方面带大家全面了解Django框架

  1. 流程
  2. 基本配置
  3. 路由系统
  4. 视图view
  5. 模板
  6. Model
  7. 中间件
  8. Form
  9. 认证系统
  10. CSRF
  11. 分页
  12. Cookie
  13. Seesion
  14. 缓存
  15. 序列化
  16. 信号
  17. admin
一、Django流程介绍

img

MVC是众所周知的模式,即:将应用程序分解成三个组成部分:model(模型),view(视图),和 controller(控制 器)。其中:
M——管理应用程序的状态(通常存储到数据库中),并约束改变状态的行为(或者叫做“业务规则”)。
C——接受外部用户的操作,根据操作访问模型获取数据,并调用“视图”显示这些数据。控制器是将“模型”和“视图”隔离,并成为二者之间的联系纽带。
V——负责把数据格式化后呈现给用户。

Django也是一个MVC框架。但是在Django中,控制器接受用户输入的部分由框架自行处理,所以 Django 里更关注的是模型(Model)、模板(Template)和视图(Views),称为 MTV模式:

​ M 代表模型(Model),即数据存取层。 该层处理与数据相关的所有事务: 如何存取、如何验证有效性、包含哪些行为以及数据之间的关系等。

​ T 代表模板(Template),即表现层。 该层处理与表现相关的决定: 如何在页面或其他类型文档中进行显示。

​ V 代表视图(View),即业务逻辑层。 该层包含存取模型及调取恰当模板的相关逻辑。 你可以把它看作模型与模板之间的桥梁。

二、Django基本配置

1. 创建django程序

  • 终端命令:django-admin startproject sitename (在当前目录下创建一个Django项目)
  • IDE创建Django程序时,本质上都是自动执行上述命令

其他常用命令:

python manage.py runserver ip:port (启动服务器,默认ip和端口为http://127.0.0.1:8000/)

python manage.py startapp appname (新建 app)

python manage.py syncdb (同步数据库命令,Django 1.7及以上版本需要用以下的命令)

python manage.py makemigrations (显示并记录所有数据的改动)

python manage.py migrate (将改动更新到数据库)

python manage.py createsuperuser (创建超级管理员)

python manage.py dbshell (数据库命令行)

python manage.py (查看命令列表)

  python manage.py inspectdb > 文件名.py  	通过数据库自动导出models类

2.程序目录

img

3.配置文件

  • 数据库

    支持SQLite 3(默认)、PostgreSQL 、MySQL、Oracle数据库的操作

    # 默认是SQLit 3 的配置
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }
    
    
    # MySQL的配置
    
    DATABASES = {
        'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME':'dbname',   #注意这里的数据库应该以utf-8编码
        'USER': 'xxx',
        'PASSWORD': 'xxx',
        'HOST': '',
        'PORT': '',
        }
    }
    
    # 对于python3的使用者们还需要再加一步操作
    # 由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替
      
    # 如下设置放置的与project同名的配置的 __init__.py文件中
      
    import pymysql
    pymysql.install_as_MySQLdb()
    
    
    # PostgreSQL配置
    DATABASES = {
        'default': {
            'NAME': 'app_data',
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'USER': 'XXX',
            'PASSWORD': 'XXX'
        }
    
    
    # Oracle配置
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.oracle',
            'NAME': 'xe',
            'USER': 'a_user',
            'PASSWORD': 'a_password',
            'HOST': '',
            'PORT': '',
        }
    }
    
    具体配置
    

    Django框架对于开发者而言高度透明化,对于不同数据库的具体使用方法是一致的,改变数据库类型只需要变动上述配置即可。

  • 静态文件添加

    # 首先在项目根目录下创建static目录
    
    # 接着在settings.py 文件下添加
    
    STATIC_URL = '/static/'  # 默认已添加,使用静态文件时的前缀
    STATICFILES_DIRS = (
            os.path.join(BASE_DIR,'static'), #行末的逗号不能漏
        )
    
    # 这样在template中就可以导入static目录下的静态文件啦
    
    # 例:
    <script src="/static/jquery-1.12.4.js"></script>
    
    settings配置
    
三、 Django 路由系统

URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。URL的加载是从配置文件中开始。

img

参数说明:

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

1、示例

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

说明:

  • 要捕获从URL中的值,用括号括起来,会当参数传入 views 视图。
  • 没有必要添加一个斜线,因为每个URL都有。例如,它^articles不是^/articles
  • 'r'前面的每个正则表达式字符串中是可选的,禁止转义

请求示例:

  • 一个请求 /articles/2005/03/ 会匹配上面列表中的第三条. Django 会调用函数 views.month_archive(request, '2005', '03').
  • /articles/2005/3/ 不会匹配上面列表中的任何条目, 因为第三条的月份需要二位数字.
  • /articles/2003/ 会匹配上第一条而不是第二条,因为匹配是按照从上到下顺序而进行的, Django 会调用函数 views.special_case_2003(request)
  • /articles/2003 不会匹配上面列表中的任何条目, 因为每个URL应该以 / 结尾.
  • /articles/2003/03/03/ 会匹配上最后一条. Django 会调用函数 views.article_detail(request, '2003', '03', '03')

2. 命名组(Named groups)

在上面的简单例子中,并没有使用正则表达式分组,在更高级的用法中,很有可能使用正则分组来匹配URL并且将分组值通过参数传递给view函数。

在Python的正则表达式中,分组的语法是 (?P<name>pattern), name表示分组名,pattern表示一些匹配正则.

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

For example:

  • A request to /articles/2005/03/ 会调用函数 views.month_archive(request, year='2005',month='03'), 而不是 views.month_archive(request, '2005', '03')
  • A request to /articles/2003/03/03/ 会调用函数 views.article_detail(request, year='2003',month='03', day='03')

常见写法实例:
img

3. 二级路由(Including)

那如果映射 url 太多怎么办,全写一个在 urlpatterns 显得繁琐,so 二级路由应用而生

from django.conf.urls import include, url
 
from apps.main import views as main_views
from credit import views as credit_views
 
extra_patterns = [
    url(r'^reports/$', credit_views.report),
    url(r'^reports/(?P<id>[0-9]+)/$', credit_views.report),
    url(r'^charge/$', credit_views.charge),
]
 
urlpatterns = [
    url(r'^$', main_views.homepage),
    url(r'^help/', include('apps.help.urls')),
    url(r'^credit/', include(extra_patterns)),
]

在上面这个例子中,如果请求url为 /credit/reports/ 则会调用函数 credit_views.report()

使用二级路由也可以减少代码冗余,使代码更加简洁易懂

# 原始版本
from django.conf.urls import url
from . import views
 
urlpatterns = [
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/history/$', views.history),
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/edit/$', views.edit),
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/discuss/$', views.discuss),
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/permissions/$', views.permissions),
]
 
 
# 改进版本
from django.conf.urls import include, url
from . import views
 
urlpatterns = [
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/', include([
        url(r'^history/$', views.history),
        url(r'^edit/$', views.edit),
        url(r'^discuss/$', views.discuss),
        url(r'^permissions/$', views.permissions),
    ])),
]

4. 添加额外的参数

URLconfs 有一个钩子可以让你加入一些额外的参数到view函数中.

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 将会调用函数l views.year_archive(request, year='2005',foo='bar').

需要注意的是,当你加上参数时,对应函数views.year_archive必须加上一个参数,参数名也必须命名为 foo,如下:

def year_archive(request, year,foo):
    print(foo)
    return render(request, 'index.html')

5. 别名的使用

url(r'^index',views.index,name='bieming')

url中还支持name参数的配置,如果配置了name属性,在模板的文件中就可以使用name值来代替相应的url值.

我们来看一个例子:

urlpatterns = [
    url(r'^index/',views.index,name='bieming'),
    url(r'^admin/', admin.site.urls),
    url(r'^articles/([0-9]{4})/$', views.year_archive)
]
###################

def index(req):
    if req.method=='POST':
        username=req.POST.get('username')
        password=req.POST.get('password')
        if username=='alex' and password=='123':
            return HttpResponse("登陆成功")



    return render(req,'index.html')

#####################

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{#     <form action="/index/" method="post">#}
{#     这里只要使用bieming即可代替/index #}
     <form action="{% url 'bieming' %}" method="post">
         用户名:<input type="text" name="username">
         密码:<input type="password" name="password">
         <input type="submit" value="submit">
     </form>
</body>
</html>


#######################

name的应用

6. 指定view的默认配置

# URLconf
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),
]
 
# View (in blog/views.py)
def page(request, num="1"):
    # Output the appropriate page of blog entries, according to num.
    ...

在上述的例子中,两个 URL 模式指向同一个视图 views.page但第一图案不捕获从 URL 任何东西。如果第一个模式匹配,该 page()函数将使用它的默认参数 num"1"。如果第二图案相匹配时, page()将使用任何 num值由正则表达式捕获

四、 Django Views(视图函数)

http请求中产生两个核心对象:

http请求:HttpRequest对象

http响应:HttpResponse对象

1. HttpRequest对象

当请求一个页面时,Django 创建一个 HttpRequest对象包含原数据的请求。然后 Django 加载适当的视图,通过 HttpRequest作为视图函数的第一个参数。每个视图负责返回一个HttpResponse目标

path:       请求页面的全路径,不包括域名

method:     请求中使用的HTTP方法的字符串表示。全大写表示。例如

                   if  req.method=="GET":

                             do_something()

                   elseif req.method=="POST":

                             do_something_else()

GET:         包含所有HTTP GET参数的类字典对象

POST:       包含所有HTTP POST参数的类字典对象

             服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过
             HTTP POST方法提交请求,但是表单中可能没有数据,因此不能使用
             if req.POST来判断是否使用了HTTP POST 方法;应该使用  if req.method=="POST"



COOKIES:     包含所有cookies的标准Python字典对象;keys和values都是字符串。

FILES:      包含所有上传文件的类字典对象;FILES中的每一个Key都是<input type="file" name="" />标签中 
            name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:

            filename:      上传文件名,用字符串表示
            content_type:   上传文件的Content Type
            content:       上传文件的原始内容


user:       是一个django.contrib.auth.models.User对象,代表当前登陆的用户。如果访问用户当前
             没有登陆,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。你
             可以通过user的is_authenticated()方法来辨别用户是否登陆:
             if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware
             时该属性才可用

session:    唯一可读写的属性,代表当前会话的字典对象;自己有激活Django中的session支持时该属性才可用。

META:       一个标准的Python字典包含所有可用的HTTP头。可用标题取决于客户端和服务器,但这里是一些例子:

            CONTENT_LENGTH       – 请求体的长度(一个字符串)。
            CONTENT_TYPE         – 请求体的类型。
            HTTP_ACCEPT          - 为响应–可以接受的内容类型。
            HTTP_ACCEPT_ENCODING – 接受编码的响应
            HTTP_ACCEPT_LANGUAGE – 接受语言的反应
            HTTP_HOST            – 客户端发送的HTTP主机头。
            HTTP_REFERER         – 参考页面
            HTTP_USER_AGENT      – 客户端的用户代理字符串。
            QUERY_STRING         – 查询字符串,作为一个单一的(分析的)字符串。
            REMOTE_ADDR          – 客户端的IP地址
            REMOTE_HOST          – 客户端的主机名
            REMOTE_USER          – 用户通过Web服务器的身份验证。
            REQUEST_METHOD       – 字符串,如"GET""POST"
            SERVER_NAME          – 服务器的主机名
            SERVER_PORT          – 服务器的端口(一个字符串)。

HttpRequest对象属性

2.HttpResponse对象

对于HttpRequest对象来说,是由django自动创建的,但是,HttpResponse对象就必须我们自己创建。每个view请求处理方法必须返回一个HttpResponse对象。

在HttpResponse对象上扩展的常用方法:

  • 页面渲染:render(推荐),render_to_response,
  • 页面跳转:redirect(重定向)
  • locals: 可以直接将对应视图函数中所有的变量传给模板

img

值得注意的是对于页面渲染的方法中,render和render_to_response使用方法和功能类似,但是render功能更为强大,推荐使用

3. render()

render( request,template_name, context=None, content_type=None, status=None, using=None) 结合给定的模板与一个给定的上下文,返回一个字典HttpResponse在渲染文本对象

所需要的参数:

template_name 模板的名称

可选参数:context 一组字典的值添加到模板中。默认情况下,这是一个空的字典。

content_type MIME类型用于生成文档。

status 为响应状态代码。默认值为200

from django.shortcuts import render

def my_view(request):
    # View code here...
    return render(request, 'myapp/index.html', {
        'foo': 'bar',
    }, content_type='application/xhtml+xml')

render示例
五、模板

1. 模板的执行

模板的创建过程,对于模版,其实就是读取模板(其中嵌套着模板标签),然后将 Model 中获取的数据插入到模板中,最后将信息返回给用户。

# view.py

def index(request):
    return render(request, 'index.html', {'title':'welcome'})


# index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>
        <h1>{{ title }}</h1>
    </div>

</body>
</html>

示例

2. 模板语言

模板中也有自己的语言,该语言可以实现数据展示

{{ item }}	变量

<!-- for 标签 -->
{% for item in items %}
	<a>{{ item }}</a>
{% endfor %}

<!-- if 标签 -->
{% if condition1 %}
   display 1
{% elif condition2 %}
   display 2
{% else %}
   display 3
{% endif %}

<!-- 过滤器 -->
{{ name|lower }}	{{ name }} 变量被过滤器 lower 处理后,文档大写转换文本为小写
{{ my_list|first|upper }} 	一个过滤器管道的输出又可以作为下一个管道的输入
{{ bio|truncatewords:"30" }}	将显示变量 bio 的前30个词

<!-- 模板继承 -->
<!-- 模板可以用继承的方式来实现复用 -->
{%extends "base.html" %}
 
{% block mainbody %}
<p>继承了 base.html 文件</p>
{% endblock %}
六、 Model

Django提供了一个抽象层(“Model”)来构建和管理Web应用程序的数据。

django中遵循 Code Frist 的原则,即:根据代码中定义的类来自动生成数据库表。

关系对象映射(Object Relational Mapping,简称ORM)。

a.基本结构

from django.db import models
    
 class userinfo(models.Model):
    name = models.CharField(max_length=30)
    email = models.EmailField()
    memo = models.TextField()

可选参数:

1、null=True 数据库中字段是否可以为空
2、blank=True django的Admin中添加数据时是否可允许空值
3、primary_key=False 主键,对AutoField设置主键后,就会代替原来默认的自增id4、auto_now和auto_now_add
  auto_now  表示每次更新都会更新这个时间
  auto_now_add  表示只是第一次创建时添加,之后的更新不再改变
5、choices
     GENDER_CHOICE = (
          (u'M', u'Male'),
          (u'F', u'Female'),
      )
     gender = models.CharField(max_length=2,choices=GENDER_CHOICE)
6、max_length 最大长度
7、default  默认值
8、verbose_name  Admin中字段的显示名称
9、name|db_column 数据库中的字段名称
10、unique=True  创建唯一索引
11、db_index = True  创建普通索引
12、editable=True  在Admin里是否可编辑
13、error_messages=None  错误提示
14、auto_created=False  自动创建
15、help_text  在Admin中提示帮助信息
16、validators=[]  验证
17、upload-to  文件上传路径

字段类型

1、models.AutoField  自增列=int(11)
  如果没有的话,默认会生成一个名称为id的列,如果要显示的定义一个自增列,必须把该列设置为主键(primary_key=True)
2、models.CharField  字符串类型字段 必须加max_length参数
3、models.BooleanField 布尔类型字段=tinyint(1)  不能为空,Blank=True
4、models.ComaSeparatedIntegerField  用逗号分割的数字类型=varchar 继承CharField,所以必须加max_lenght参数
5、models.DateField  日期字段类型date
  参数auto_now=True表示每次更新都会更新这个时间;参数auto_now_add表示只是第一次创建时添加,之后的更新不再改变
6、models.DateTimeField  日期字段类型datetime  同DateField的参数
7、models.Decimal  十进制小数类型=decimal
  必须指定整数位max_digits和小数位decimal_places
8、models.EmailField  字符串类型(正则表达式邮箱)=varchar  对字符串进行正则表达式验证
9、models.FloatField  浮点类型=double
10、models.IntegerField  整形
11、models.BigIntegerField 长整形
  integer_field_ranges = {
    'SmallIntegerField': (-32768, 32767),
    'IntegerField': (-2147483648, 2147483647),
    'BigIntegerField': (-9223372036854775808, 9223372036854775807),
    'PositiveSmallIntegerField': (0, 32767),
    'PositiveIntegerField': (0, 2147483647),
  }
12、models.IPAddressField  字符串类型(ip4正则表达式)
13、models.GenericIPAddressField  字符串类型(ip4和ip6是可选的)
  参数protocol可以是:both、ipv4、ipv6  验证时,会根据设置进行报错
14、models.NullBooleanField  允许为空的布尔类型
15、models.PositiveIntegerFiel  正Integer
16、models.PositiveSmallIntegerField  正smallInteger
17、models.SlugField  减号、下划线、字母、数字
18、models.SmallIntegerField  数字
  数据库中的字段有:tinyint、smallint、int、bigint
19、models.TextField  字符串=longtext
20、models.TimeField  时间 HH:MM[:ss[.uuuuuu]]
21、models.URLField  字符串类型,地址正则表达式
22、models.BinaryField 二进制
23、models.ImageField   图片
24、models.FilePathField 文件

实例:

class UserInfo(models.Model):
    name = models.CharField(max_length=32)
    ctime = models.DateTimeField(auto_now_add=True) #每当你创建一行数据时,Django就会在该行数据中增加一个ctime字段
    uptime = models.DateTimeField(auto_now=True) #当前表任何一行数据有更新时,Django就会自动更新该字段.
    #下面两项是新增的字段,注意新增时参数的设置,否则在命令行创建数据库时报错,null=True表示在数据库中该字段可以为空,default='xxx'表示默认值
    email_1 = models.EmailField(max_length=32,null=True)
    email_2 = models.EmailField(max_length=32,default='aaa@qq.com')
    #新增字段,blank=True表示admin后台可以为空
    ip = models.GenericIPAddressField(protocol='ipv4',null=True,blank=True)
    #upload_to='upload'表示用户上传数据存储的位置,这里需要注意:在数据库中实际保存的并不是文件,而是文件存放的路径
    img = models.ImageField(null=True,blank=True,upload_to='upload')
    #下面的__unicode__(self)方法,表示当输出这个类创建的对象时,默认会输出这个对象的name字段
    def __str__(self):
        return self.name

models 的CURD

# 增
1.Entry.objects.create(属性1=1,属性2=2)
返回值:成功,创建好实体对象
	   失败,返回None
    
2.创建一个Entry对象,通过save()保存
obj = Entry(属性1=1,属性2=2)
obj.属性 = 值
obj.save()

3.通过字典创建
dic = {
    '属性1''值1''属性2''值2'
}
Entry.objects.create(**dic)

# 删
Entry.objects.filter(name='seven').delete()

# 改
Entry.objects.filter(name='seven').update(gender='0')  # 多条数据一起修改

obj = Entry.objects.get(id=1)
obj.c1 = 'seven'
obj.save()

# 查
1. Entry.objects.all()	获取所有查询结果,返回QuerySet,本质是封装了若干对象的列表
2. Entry.objects.values('列名1', '列名2') 查询表中数据的部分列,封装到字典中,再封装到QuerySet中
										本质是封装了若干字典的列表
3. Entry.objects.values_list('列名1', '列名2') 将数据封装到元组中再封装到列表中
4. Entry.bojects.order_by('列1', '-列2') 默认是升序排序,列名前加-,则表示降序排序
5. Entry.objects.get(条件)  只能查询出一条结果,返回单个实体对象
6. Entry.objects.filter(条件) 
非等值条件需要使用Field Lookups(查询谓词)
语法:Entry.objects.filter(属性__查询谓词=)

查询谓词:
__exact : =
__gt : >
__gte : >=
__lt : <
__lte : <=
__contains : like '%..%'
__startswith : like '..%'
__endswith : like '%..'
__in : in
__range : between ... and ...
__year : 获取时间日期字段中的year部分

7. Entry.objects.exclude(id=1) 用法:exclude(条件), 表示对条件取反
8.聚合查询(不带分组)
方法:aggregate(列名=聚合函数('列'))
ex: Entry.objects.aggregate(sumAge=Sum('age'))
聚合函数:
1.Avg(): 平均值
2.Count() : 数量
3.Sum() : 求和
4.Min() : 求最小值
5.Max() : 求最大值    

9.聚合查询(带分组)
方法:annotate(=聚合函数('列'))
ex: 按 班级 分组 查询平均年龄
    Entry.objects.values('class').annotate(avgAge=Avg('age')).all()

    集结 where,分组查询,having 于一体的查询接口
    Entry.objects
    .filter(id__gte=3)  # where 子句  
    .values('class') # group by 子句
    .annotate(avgAge=Avg('age')) # 查询聚合函数
    .filter(avgAge__gte=30) # having 子句

其他操作

1.F查询 和 Q查询
	1.F()
	作用:在执行过程中获取某列的值
    from django.db.models import F
    F('列名') :得到对应列的值
    
    Author.objects.all().update(age=F('age')+10)
        
	2.Q()
	作用:在查询条件中可以完成 or 操作
    from django.db.models import Q
    Q(条件1)|Q(条件2)

    查询 id大于等于3 或 年龄 < 40 的人的信息
    Author.objects.filter(Q(id__gte=3)|Q(age__lt=40))

2.原生的数据库操作方法
    1.查询
    函数:raw(sql语句)
    语法:Entry.objects.raw(sql)
    返回:QuerySet
    

使用后台管理Models

	1.后台的配置
		登录地址 :http://localhost:8000/admin

		创建后台管理员(超级用户):
			./manage.py createsuperuser
			Username : 输入用户名,默认为系统账户名
			Email Address : 电子邮件
			Password : 密码
			Password(again) : 确认密码
	2.Models 的基本管理
		1.在应用中的 admin.py 中注册要管理的实体类
			1.admin.py
				作用:注册要管理的Models类,只有注册后才能管理
			2.注册Models
				from .models import *
				admin.site.register(Entry)
        2.通过定义Models类中的内部类Meta,提高在后台的可读性
			class Author(models.Model):
				... ...
				class Meta:
					1.db_table
						指定该实体类映射到的表的名称
						(该属性设置完成后需要同步回数据库)
					2.verbose_name
						定义类在 admin 中显示的名字(单数)
					3.verbose_name_plural
						定义类在 admin 中显示的名字(复数)
					4.ordering
						指定数据在后台管理中显示的排序方式
						取值为一个列表,指定排序列,默认升序,降序使用-       
		
	3.Models 的高级管理
		1.在 admin.py 中创建高级管理类并注册
			1.定义 EntryAdmin 类 ,继承自 admin.ModelAdmin
				class AuthorAdmin(admin.ModelAdmin):
					pass
			2.注册高级管理类
				admin.site.register(Entry,EntryAdmin)
				ex:
					admin.site.register(Author,AuthorAdmin)
		2.允许在 EntryAdmin 中增加的属性
			1.list_display
				作用:定义在列表页上显示的字段们
				取值:由属性名组成的元组或列表
			2.list_display_links
				作用:定义在列表页上也能够链接到详情页的字段们
				取值:同上
				注意:取值必须要出现在list_display中
			3.list_editable
				作用:定义在列表页上就能够修改的字段们
				取值:同上
				注意:取值必须要出现在list_display中但不能出现在list_display_links中
			4.search_fields
				作用:定义搜索栏中允许搜索的字段值们
				取值:同上
			5.list_filter
				作用:列表页的右侧在增加过滤器实现快速筛选
				取值:同上
			6.date_hierarchy
				作用:列表页的顶部增加一个时间选择器,
				取值:属性必须是 DateField 或 DateTimeField 的列
			7.fields
				作用:在详情页面中,指定要显示哪些字段并按照什么样的顺序显示
				取值:由属性名组成的元组或列表
			8.fieldsets
				作用:在详情页面中对字段们进行分组显示
				注意:fieldset 与 fields 不能共存
				取值:
					fieldsets = (
						#分组1
						('分组名称',{
							'fields':('属性1','属性2'),
							'classes':('collapse',)
						}),
						#分组2
						()
					)

实例:# admin.py

from django.contrib import admin
from .models import *

class PublisherAdmin(admin.ModelAdmin):
    # 1.指定列表页中显示name,address,city字段
    list_display = ('name', 'address', 'city')
    # 2.列表页中address,city是可编辑的
    list_editable = ('address', 'city')
    # 3.右侧增加过滤器,允许按照city进行筛选
    list_filter = ('city',)
    # 4.顶部增加搜索框,允许按照Name和website进行搜索
    search_fields = ('name', 'website')
    # 5.详情页中分组显示
    fieldsets = (
        (
            '基本选项', {
                'fields': ('name', 'address', 'city'),
            }
        ),
        (
            '高级选项', {
                'fields': ('country', 'website'),
                'classes': ('collapse',),
            }
        )
        )

# Register your models here.
admin.site.register(Publisher, PublisherAdmin)

Models 关系映射

	1.一对一映射
		1.语法
			在关联的两个类中的任何一个类都可以增加对另一个类的引用

			属性 = models.OneToOneField(Entry)

			ex:
				class Author(models.Model):
					.... ....

				class Wife(models.Model):
					.... ....
					#增加对Author的一对一引用
					author = models.OneToOneField(Author)
			
			在数据库中:
				会生成一个外键(author_id)列在 wife 表中,会引用在 author 表的主键
			在 Author 中:
				增加一个隐式属性 - wife,来表示author所对应的wife(其实就是反向引用属性)
		2.查询
			1.正向查询 :通过 Wife 找 Author
				特点:通过自定义的关联属性查找对应实体
				wife = Wife.objects.get(id=1)
				author = wife.author
			2.反向查询 :通过 Author 找 Wife
				特点:通过反向引用属性查找对应的实体
				author = Author.objects.get(id=1)
				wife = author.wife
	
	2.一对多映射
		1.语法
			在"多"表中增加对"一"表的外键引用
			在"多"实体中增加对"一"实体的引用
			在 "多" 实体中增加:属性 = models.ForeignKey(Entry)

			ex: Book() 和 Publisher()
			class Book(models.Model)
				... ...
				publisher = models.ForeignKey(Publisher)
			
			数据库中体现:
				Book 表中 增加一个外键列 publisher_id ,引用自 Publisher 表中的主键
			在实体类中的:
				1.Book 中会有一个 publisher 属性 来表示对应的 Publisher 的对象
				2.Publisher 中会有一个隐式属性 - book_set,用来表示该 publisher 对应的所有的 Book 				   对象的查询
	3.多对多映射
        1.语法
            在关联的两个类的任意一个类中,增加:属性 = models.ManyToManyField(Entry)
            ex: Author 与 Book 可以是多对多关联关系
                1位Author可以出版多本Book
                1本Book可以由多位Author联合编写

                class Author(models.Model)
                .... ....

                class Book(models.Model):
                    ... ...
                    authors = models.ManyToManyField(Author)

                正向引用:
                在 Book 中通过 authors 来表示对应的所有的书籍的查询
                反向引用:
                在 Author 中通过 book_set 来表示对应的所有的作者们的查询
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值