澳门新蒲京娱乐


ThinkPHP在措施中计算耗费时间【新蒲京官方下载】

thinkphp在app接口开发过程中的通讯数据的封装,PHP开发APP接口实战006

thinkphp网页模版中调用函数实例

在做网址的时候,数据库中存放用户消息的USELacrosse表,里面富含id,name字段等等,不过大家做项目中,其余表需求调用用户消息(查询user表),比方说用户名,注册时间…

Django框架

[toc]

然而假诺通过用户id来只获得用户名,我以为没有供给在去写一个询问语句,举例说怎么着外集合,联合查询,

焦点配置

实际只供给写一个共用函数,下边包车型客车PHP代码是依据thinkphp框架的,如下:

1.安装

pip3 install django
 //获取用户姓名  function getUserName($uid,$lang='zh') {   if ($uid){    $uModel = new Model();    $uname = $uModel->query("SELECT username FROM wo_user WHERE user_id = $uid");    return $uname[0]['username'];   }   else return '用户不存在!';  }  

2.创建django project

下一场径直在模板中调用那么些函数就能够,模版中代码如下:

透过极端成立

1.创建django程序

django-admin startproject <proecjt名>
例如:
    django-admin startproject mysite

2.成立project中的app文件目录

python manage.py startapp <app名>
例如:
    python manage.py startapp app01

3.进去程序目录

cd mysite

4.起动socket服务端,等待用户发送央浼(不写端口暗许九千)

python manage.py runserver 127.0.0.1:8080

5.任何命令

python manage.py createsuperuser  # 用于django admin创建超级用户
python manage.py makemigrations  # 记录对models.py文件的改动
python manage.py migrate  # 将改动映射到数据库
{$vo.user_id|getUsername}  

通过IDE创建

经过IDE(pycharm等)成立django project,以上命令均自动实施

如此就足以在全方位网址中经过id获得用户名.

3.project索引结构

目录结构介绍

- mysite(~/PycharmProjects/mysite)
    |- app01/ 
        |- admin.py  # Django自带管理配置后台
        |- models.py  # 写类,根据类创建数据库表
        |- test.py  # 单元测试
        |- views.py  # 视图函数
        |- apps.py  # 配置文件 
    |- mysite/
        |- __init__.py
        |- setting.py
        |- urls.py
        |- wsgi.py 
    |- static/
    |- templates/
    |- utils/
    |- manage.py

4.setting.py安插文件

指定template目录

在settings.py 文件中,内定template文件路线

TEMPLATES = [
    {
        ...
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        ...
     },

指定static目录

在settings.py 文件中,添加STATICFILES_DIRubiconS,注意要加逗号

STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),  # 逗号
)

安插数据库

  • Django暗中同意使用的数据库是sqllite3,大家要选择mysql就须要采用第三方工具连接数据库
  • Django内部接二连三mysql的第三方工具是MySQLDB,可是python3不再帮忙MySQLDB
  • 据此得修改django暗中认可连接mysql格局为pymysql

1.创建mysql数据库
2.修改配置settings.py

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

3.退换项目同名文件下__init__.py文件
pymsql替换内部的myqldb,修改django暗中同意连接mysql第三方工具

import pymysql
pymysql.install_as_MySQLdb()

路由系统

路由系统简单介绍

路由正是在urls.py文件中的url和函数的照顾关系

# urls.py文件
from django.conf.urls import url
from django.contrib import admin

# 对应关系
urlpatterns = [
    # url(r'^admin/', admin.site.urls),
    url(r'^login/', login),  # 对应关系
]

其中,

  • 对应涉及:/login/, login
  • 乞求参数:request
  • 回来情势:HttpResponse\render\redirect

案例

from django.conf.urls import url
from django.contrib import admin

from django.shortcuts import HttpResponse,render,redirect
def login(request):
    print(request.GET)
    if request.method == "GET":
        return render(request,'login.html')
    else:
        # 用户POST提交的数据(请求体)
        u = request.POST.get('user')
        p = request.POST.get('pwd')
        if u == 'root' and p == '123':
            # 登录成功
            return redirect('/index/')
        else:
            # 登录失败
            return render(request,'login.html',{'msg': '用户名或密码错误'})

urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^login/', login),
url(r'^index/', index),
]

1.单一同由相应

url(r'^index$', views.index),

2.基柳盈瑄则的路由

依照正则的路由能够传递参数,依照传递格局得以分为,静态路由和动态路由三种

静态路由

大家都晓得url能够透过get格局传参数,这种情势被称作静态路由

url(r'^index/?id=12', views.index),  

# 对应views.py中的def index(request),可以根据request.GET.get('id')获取参数值

动态路由

路由中的url部分其实正是正则表达式,所以能够运用正则表明式代替get传参数,传递方式有两种传递地点参数 和 传递命名参数

职位参数

地方参数对参数顺序有供给

url(r'^index/(\w+)/', views.index),  # (\w+)可以匹配任意字母或数字或下划线或汉字作为位置参数,对参数顺序有要求

# 匹配的参数会被def index(request,a)中的参数a接收
取名参数

参数通过参数名对应,所以对一一没必要

url(r'^index/(?P<a2>\d+)/(?P<a1>\d+)/', views.index),   # (?P<a1>\d+)可以指定匹配任意数字并且参数名为a1

# 匹配的参数被def index(request,a1,a2)中的参数a1接收,对参数顺序没有要求

注意:地方传递和命名传递不可混用,所以利用要统一

终止符

因为url就是为正则表明式,所以url前部相配成功后就能调用函数,所以为了完美合作可以在url结尾跟/也许$

url(r'^index$', views.index),  # 只会匹配index
url(r'^index', views.index),  # 会全部匹配index开头字符串

伪静态

SEO(Search Engine
Optimization,搜索引擎优化)静态网页的寻觅权重高于动态网页,所以经过伪造动态网页为静态网页后缀到达权重增添的目标

url(r'^index/(/w+).html$', views.index),  # 表示页面以.html结尾

从而,url正则表明式情势 + 伪静态 = 动态路由
不出现‘?id=..’get传参的写法,能够巩固SEO的找寻权重

暗中认可页面

假定用户输入url不设有,能够制定到暗许页面

url(r'^', <指定函数名>),

3.加多额外的参数

url(r'^manage/(?P<title>\w*)', views.manage,{'name':'kirs'}),

4.路由分发

依靠据app对路由规则实行归类

叁个Django项目中恐怕会有广伟大的事业务线(众多app),假诺一都应用同三个路由系统大概会导致url重名难题,所以能够依附各个app建设构造本身的urls.py文件,通过项指标路由系统来找到各自app的路由对应关系

1.在app01中新建urls.py,并import自己的views

from django.conf.urls import url
from app01 import views
urlpatterns = [
    url(r'^index.html$', views.index),
]

2.在品种的urls.py中import包include,
在类型的urls.py中写入app01url和include内容

from django.conf.urls import url,include
urlpatterns = [
    url(r'^app01/', include('app01.urls')), 
]

这么,url来了,项目路由会先找对应app,找到后,去对应app中的urls中找对应提到

5.url涉及命名

给url与函数关系命名

视图函数应用

西魏在视图函数中得以依据外号反生成url

- 1.首先,urls.py中
    url(r'^index/', views.index, name='name1'),

- 2.在views.py中import包reverse
    from django.urls import reverse
    url = reverse('name1')  # 获取到/index/

反生成带特定 地方参数的url

- 1.urls.py中
    url(r'^index/(\w+)/', views.index, name='name1'),
- 2.在views.py中
    from django.urls import reverse
    url = reverse('name1',args=(abc,))  # 获取到/index/abc/

反生成带特定 命名参数的url

- 1.urls.py中
    url(r'^index/(?P<b1>\w+)/', views.index, name='name1'),
- 2.在views.py中
    from django.urls import reverse
    url = reverse('name1',kwargs={'b1':abcd,})  # 获取到/index/abcd/

html应用

他日在html页面中可以依据小名取得url地址

- 1.urls.py中
    url(r'^index/', views.index, name='name1'),

- 2.a标签取url 
    - 原来写法
        <a href="/index/"></a>

    - 现在写法
        <a href="{%%20url%20"name1" %}"></a>  # 效果就是/index/

动态传递参数如何是好?

- 1.urls.py中
    url(r'^index/(\w+)/(\w+)/', views.index, name='name1'),

- 2.a标签取url
    - 原来写法: 
        <a href="/index/(\w+)/(\w+)/"></a>  
    - 现在写法:
        <a href="{%%20url%20"name1" 参数1 参数2 %}"></a>  # 效果就是/index/参数1/参数2
        # <a href="{%%20url%20"name1" x y %}"></a>  # 效果就是/index/peter/alex

PS:url与函数关系命名能够用于权限管理简化存款和储蓄内容:数据仓库储存款和储蓄外号就能够,就绝不存款和储蓄不长的url地址


模版引擎

模版的实施

模版的创始进程,对于模版,其实就是读取模版(其中嵌套着沙盘标签),然后将
Model 中获得的数目插入到模版中,最后将音讯重回给用户。

内部,再次回到情势:HttpResponse\render\redirect

#views.py
from django.shortcuts import HttpResponse, render, redirect

# 视图函数
def login(request): 
    # return HttpResponse('massage')  # 直接获取内容返回用户
    return render(request, 'login.html', {'key':'value'})  # 自动找到templates路径下的login.html文件,读取内容并返回给用户
    # return redirect('/login/')  # 重定向文件

render 再次来到参数

回到参数能够是

字符串:'name': 'alex',
列表:'users':['tom','kirs'],
字典:'user_dict':{'k1': '123','k2':'234'},
列表套字典:
'user_list_dict': [
                {'id':1, 'name': 'alex', 'email': 'alex3714@163.com'},
                {'id':2, 'name': 'alex2', 'email': 'alex3714@1632.com'},
                {'id':3, 'name': 'alex3', 'email': 'alex3713@1632.com'},
            ]

html 中取值,直接通过.取值

{{users.0}}  {{user.1}}
{{user_dict.k1}}  {{user_dict.k2}}

案例

def index(request):
    # return HttpResponse('Index')
    return render(
        request,
        'index.html',
        {
            'name': 'alex',
            'users':['李志','李杰'],
            'user_dict':{'k1': 'v1','k2':'v2'},
            'user_list_dict': [
                {'id':1, 'name': 'alex', 'email': 'alex3714@163.com'},
                {'id':2, 'name': 'alex2', 'email': 'alex3714@1632.com'},
                {'id':3, 'name': 'alex3', 'email': 'alex3713@1632.com'},
            ]
        }
    )

模版语言

html 渲染方式

{{ }}

{% for i in [列表|字典] %}
    {{i.列1}}
    {{i.列2}}
    ...
{% endfor%}

{% if 条件%}
    ...
{% else %}
    ...
{% endif %}

母版

前边说过的母版正是将公用内容存到html,其余子板extends就能够

{% extends "base.html" %}

include

类似于python中的import
能够自定义html小组件,将小组件倒入别的页面使用,并且三个页面吗能够屡屡导入

{% include 'pub.html' %}  # pub.html为组件

#pub.html
<div>
<div class='...'>{{ name }}<>
<div>

PS:并且组件中得以承受后台参数

模版引擎

在模板引擎中流传函数名,自动实行函数,不用加括号
透过后台传来的字典具备艺术
keys

- 遍历key
    {% for i in user_list.keys%}
        {{i}}
    {% endfor%}

values

- 遍历value
    {% for i in user_list.values%}
        {{i}}
    {% endfor%}

items

- 遍历key和value
    {% for k,v in user_list.items%}
        {{k}}
        {{v}}
    {% endfor%}

内置方法

放置方法通过|方法名推行

- 将字符串大写
    {{ name|upper }}

模版自定义函数

创办模版自定义函数simple_filter

1.在app创设二个名称为templatetags文件(名称不可改)
2.开立大肆templatetags/xx.py文件,函数增添装饰器@register.filter

#xx.py
from django import template

register = temlate.Library()

@register.filter
def my_upper(value):
    return value.upper()

3.导入文本:在html文件中程导弹入以前创制的 xx.py 文件名

{% load xxx %}

4.使用:

{{name|my_upper}}

5.settings.py注册app

INSTALLED_APPS = (
...
'app',
)

开创模版自定义函数simple_filter最八只可以有多少个参数,然而能够做标准判别

- 最多两个参数,方式: {{第一个参数|函数名称:"第二个参数"}}
    def my_upper(value,arg):
        return value+arg

    {{name|my_upper:'abc'}}
- 可以做条件判断

成立模版自定义函数simple_tag

在上述创设进度中,要是函数扩大装饰器@register.simple_tag

    @register.simple_tag
    def my_lower(value):
        return value.lower()

行使时参数个数无界定

- 参数无限制:{% 函数名 参数 参数 ...%}
    def my_lower(value,arg1,arg2,...):
        return value + arg1 + arg2 +...

    {% my_lower name 'abc' 'bcd' ...%}

视图函数

request 诉求音信

request.method – 用户央求方法,GET或然POST
request.GET – 获取GET方式交给的数量
request.POST — 获取POST情势提交的数码

request.GET.get()
request.POST.get()
request.POST.getlist() – 获取列表

当中,客户端POST格局提交,request一样能够赢得GET数据,反之不得以

视图函数 CBV FBV

路由系统经过反射格局相配method(post、get、put等)。

用户发来呼吁,url相配到类,将method当作参数字传送入类,通过getattr找到相应措施。

FBV (Function-based views)

路由系统中,url对应函数正是FBV

urls.py

- 直接跟方法名
    url(r'^login.html$',views.login),

views.py

- 类名需要继承View,可以定义get、post等方法
    def login(request):
        return render(request, "login.html")

CBV (Class-based views)

同等,url也足以对应类,那么那就是CBV

urls.py

- 类名后跟.as_view()
    url(r'^login.html$',views.Login.as_view()),

views.py

- 类名需要继承View,可以定义get、post等方法
    from django.views import View

    class Login(View):
        def get(self, request):
            return render(request, "login.html")

        def post(self, request):
            print(request.POST.get("user"))
            return HttpResponse("login.post")

from表单唯有get、post方法,ajax不唯有有post和get方法,还会有好多任何方法,如put、delete等
PS:约定俗成:get查 post创制 put更新 delete删除

dispatch 方法

在CBV的get、post方法施行以前View内部会先进行dispatch方法

def dispatch(self, request, *args, **kwargs):
   if request.method.lower() in self.http_method_names:
       handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
   else:
       handler = self.http_method_not_allowed
   return handler(request, *args, **kwargs)

为此大家得以重写dispatch方法,起到邻近装饰器效率

装饰get、post等方法

def dispatch(self,request,*args,**kwargs):
    #执行get、post前代码
    func = super(Login,self).dispatch(request,*args,**kwargs)
    #执行get、post后代码
    return func

中间件

原理介绍

django
中的中间件(middleware),在django中,中间件其实就是二个类,在呼吁到来和了结后,django会依照自身的规则在合适的时机施行中间件中相应的艺术。

请求-->
        中间件类1方法1-->
                        中间件类2方法1-->
                                       ...-->
                                             路由系系统and视图函数 
                                       ...<--
                        中间件类2方法2<--
        中间件类1方法2<--             
响应<--   

其中,
方法1都是 process_request(),
方法二都是 process_response()

在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES
变量,当中每贰个要素便是叁在那之中间件

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

伸手依照MIDDLEWARE中的中间件顺序实施,假使中间叁在那之中间件在process_request()出现谬误,就能平素奉行那些中间件的process_response(),哀求停止继续实践,再次来到错误消息

请求-->
        中间件类1方法1-->
                        中间件类2方法1-出错
                                       |
                        中间件类2方法2<--
        中间件类1方法2<--             
响应<--   

自定义中间件

应用境遇:于用户认证,取代auth装饰器,省去给任何视图函数增加装饰器

1.新建py文件,倒入入MiddlewareMixin
2.类中等学校函授数:process_request、process_response
3.报了名中间件py文件

# m1.py
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class M1(MiddlewareMixin):
    def process_request(self,request):
        print('m1.process_request')

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print('m1.process_view')
        # response = callback(request,*callback_args,**callback_kwargs)
        # return response

    def process_response(self,request,response):
        print('m1.process_response')
        return response

    def process_exception(self, request, exception):
        print('m1.process_exception')

    def process_template_response(self,request,response):
        """
        视图函数的返回值中,如果有render方法,才被调用
        :param request:
        :param response:
        :return:
        """
        print('m1.process_template_response')
        return response

其中,
1.process_request
不能够有return,假如return,中间件不再继续实行,直接重返
2.process_response 必须须求return 重临值
3.proccess_view 相称到对应函数,并不会实践,
4.proccess_exception
至极管理,唯有视图函数错误才会实践,中间件会从最后三个类中的proccess_exception开端向前实践,proccess_exception全体实行完成后,再从最终一个类中的process_response初叶向前重临
5.proccess_template_view
视图函数有render,才施行,对负有央求,或部分央浼做批量拍卖,应用:记录日志功用

# settings.py
MIDDLEWARE = [
    ...
    m1.Middle1,
]

Ajax须求再次回到供给后台通过HttpResponse重返json.dumps字典数据,这几个作用能够封装成另二个类调用render,利用中间件中的proccess_template_view实现

# views.py
from django.shortcuts import render,HttpResponse,redirect

class JSONResponse:
    def __init__(self,req,status,msg):
        self.req = req
        self.status = status
        self.msg = msg
    def render(self):
        import json
        ret = {
            'status': self.status,
            'msg':self.msg
        }
        return HttpResponse(json.dumps(ret))

def test(request):
    # print('test')
    # return HttpResponse('...')
    ret = {}
    return JSONResponse(request,True,"错误信息")

PS:在django1.10中,如果process_request中有这些恐怕return,中间件会从当下类的process_response开头回到

在django1.7或者1.8中,如果process_request中有分外或然return,中间件会从最终八个类中的process_response初始向前重临


admin

Model

Django对数据库操作使用关系对象映射(Object Relational
Mapping,简称ORM),一般不利用原生sql(除非遭逢复杂sql)

ORM操作

Django中通过ORM操作数据库

ORM操作表:能够创立表、修改表、删除表(SQLAlchemy却一筹莫展修改表)

ORM操作行:增、删、改、查

Django的ORM私下认可使用的数据库是sqllite3,我们要利用mysql就供给利用第三方工具连接数据库
Django暗中同意连接mysql的第三方工具是MySQLDB,但是python3不再支持MySQLDB
因此得修改django暗许连接mysql格局为pymysql

创建表

建表前计划:配置文件

1.创办数据库
2.改变配置settings.py

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

3.退换项目同名文件下__init__.py文件
pymsql替换内部的myqldb,修改django暗许连接mysql第三方工具

import pymysql
pymysql.install_as_MySQLdb()

1.骨干组织

a.建表流程

1.写model:
models.py文件

from diango.db import models

class UserInfo(models.Model):
uid = models.BigAutoField(primary_key=True) # int自增主键,默认不写django自动增加
username = models.CharField(max_length=32) #char(32)
password = models.CharField(max_length=64)
age = models.IntegerField(default=1) # int,默认值为1,也可以null=True

2.app写入配置
settings.py,将app写入

INSTALLED_APPS = [
    ...
    'app01',
]

3.实践命令

python3 manage.py makemigrations
python3 manage.py migrate

PS:每回修改表结交涉表结构后通过命令更新就能够

4.更新表
models.py文件

class UserGroup(Models.Model):
    title = models.CharField(max_length=32)

class UserInfo(models.Model):
    ...
    ug = models.ForeignKey("UserGroup", null=True)  # 制定外键表名,可以为空,创建外键
b.数据类型字段
字符串
CharField(Field)
    - 字符类型
    - 必须提供max_length参数, max_length表示字符长度
字符串(Django Admin中采纳数据类型的同有时间包罗对应类型验证)
EmailField(CharField)
    - email
IPAddressField(Field)
    - ip
URLField(CharField)
    - url
SlugField(CharField)
    - url并提供验证支持 字母、数字、下划线、连接符(减号)
UUIDField(Field)
    - 提供对UUID格式的验证
FilePathField(Field)
    - file并提供读取文件夹下文件的功能
    - 参数:
          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   上传图片的宽度保存的数据库字段名(字符串)
CommaSeparatedIntegerField(CharField)
    - 字符串类型,格式必须为逗号分割的数字
时间
DateTimeField(DateField)
    - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
DateField(DateTimeCheckMixin, Field)
    - 日期格式      YYYY-MM-DD
数字
IntegerField()
    - 整数列(有符号的) -2147483648 ~ 2147483647
SmallIntegerField(IntegerField)
    - 小整数 -32768 ~ 32767
BigIntegerField(IntegerField)
    - 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807
FloatField(Field)
    - 浮点型
DecimalField(Field)
   - 10进制小数
   - 参数:
       max_digits,小数总长度
       decimal_places,小数位长度
布尔
BooleanField(Field)
    - 布尔值类型
NullBooleanField(Field):
    - 可以为空的布尔值
枚举(django)

枚举未有自身的字段,是由此选用别的字段达成枚举功用

color_list = (
    (1,'黑色'),
    (2,'白色'),
    (3,'蓝色')
)
color = models.IntegerField(choices=color_list)
c.字段参数
null = True 
    - 为空
default = '123' 
    - 默认值
primary_key = True 
    - 主键
max_length = 12
    - 最大长度
unique_for_date时间创建索引

db_index = True 
    - 单列索引 
unique = True 
    - 单列唯一索引 

class Meta:
    # 联合唯一索引
    unique_together = ( 
        ('email','ctime'),
    )
    # 联合索引
    index_together = ( 
        ('email','ctime'),
    )

2.连表结构

  • 一对多:models.ForeignKey(其他表)
  • 多对多:models.ManyToManyField(其他表)
  • 一对一:models.OneToOneField(其他表)
多对多

多对多以及哪些树立协同唯一索引

方式一:ForeignKey

1.关系表Love中写Class Meta

Class Love(models.Model):
    b = models.ForeignKey('Boy')
    # b = models.ForeignKey(to='Boy',to_field='id') #关联哪个表哪个字段
    g = models.ForeignKey('Girl')

    Class Meta:  # 建立唯一索引
        unique_together = [
            ('b','g'),
        ]
方式二:models.ManyToManyField

2.由此在Boy或Girl表中写 ManyToManyField(另一张表名)

class Boy(models.Model):
    name = models.CharField(max_length=32)
     m = models.ManyToManyField('Girl')

诸如此类django会自动生成两表的涉嫌表boy_m,
但是boy_m表中唯有多少个字段:id、boy_id、girl_id,因为涉及表boy_m是自动生成,未有对应类,所以无法平素通过获得涉及表对象操作,那么要如何操作呢?

对涉嫌表boy_m的操作须求先取得二个Boy对象只怕Girl对象

- 获取对象 
    obj = models.Boy.objects.filter(name='alex').first()
- 增加 
    obj.m.add(2)  # 给alex增加girl_id=2的数据
- 批量增加
    obj.m.add(1,2,...)
- 列表增加
    l = [1,2,...]
    obj.m.add(*l)

- 删除
    obj.m.remove(1)  # 给alex删除girl_id=1这条数据
- 批量删除,同添加
    obj.m.remove(1,2,...)
- 列表删除,同添加
    l = [1,2,...]
    obj.m.remove(*l)

- 重制 
    obj.m.set([1,2,...])  # 将原本的关系全部删除,插入心的关系

- 查询 
    girl_list = obj.m.all()  # 查询到的是 QuerySet列,其中是Girl object
- 条件查询
    girl_list = obj.m.filter(nick='alice')

- 清空
    obj.m.clear()  # 清空与alex有关全部数据

那正是说对于Girl对象怎么着操作关系表呢?通过 小写表名_set实现

- 获取对象 
    obj = models.Girl.objects.filter(nick='alice').first()
- 查询
    boy_list = obj.boy_set.all()
方式三:models.ManyToManyField + ForeignKey

方法一、形式二方可连用,ManyToManyField中须要though和through_田野(field)s,不过情势二中的用法唯有询问和清空有效

#models.py
class Boy(models.Model):
    name = models.CharField(max_length=32)
    m = models.ManyToManyField('Girl',through="Love",through_fields=('b','g',)) 
    # 查询和清空

class Girl(models.Model):
    nick = models.CharField(max_length=32)
    # m = models.ManyToManyField('Boy')

class Love(models.Model):
    b = models.ForeignKey('Boy')
    g = models.ForeignKey('Girl')

    class Meta:
        unique_together = [
            ('b','g'),
        ]
单表自关系

数据库中三个表中能够依赖id两两提到
举例,有UserInfo表,让当中id举办关联,怎样促成自关系?

新建关系表 + ForeignKey

新建关系表 + ForeignKey

# models.py文件
class U2U(models.Model): # 关系表
    b = models.ForeignKey('UserInfo', related_name='boys')
    g = models.ForeignKey('UserInfo', related_name='girls')
    # b = models.ForeignKey('UserInfo', related_query_name='boys')
    # g = models.ForeignKey('UserInfo', related_query_name='girls')

中间,要用到反向寻觅外号更迭,怎么着让设置别称?这里提到知识点

related_query_name = 'b'
related_name = 'a'

那般从涉嫌表中查询UserInfo表中的新闻时,使用小名即可

obj.a_set.all()  # 通过related_query_name起名
obj.a.all()  # 通过related_name起名

上述,通过ForeignKey + 关系表达成了 自关系

询问到与id为1的男子有涉及的女人nickname

    obj = models.UserInfo.objects.filter(id=1).first()  # 找到id为1的UserInfo对象obj
    result = obj.boys.all()  # 与对象obj有关的所有信息:Querset列表[U2Ud对象]
    for i in result:
        print(i.g.nickname)  # 从U2U对象正向查找g的nickname
ManyToManyField

通过ManyToManyField实现

#models.py
class UserInfo(models.Model):
    ...
    m = models.ManyToManyField('UserInfo')

始建后会生成关系表,在那之中字段:id、from_userinfo_id、to_userinfo_id,其中,from_userinfo_id存放男人id,to_userinfo_id存放女子id

查询与id=1的男子有提到的女孩子姓名

    obj = models.UserInfo.objects.filter(id=1).first()
    result = obj.m.all()
    for i in result:
        print(i.nickname)

其中,obj.m是将obj作为from_userinfo_id,查询所有的to_userinfo_id

查询到与id为4的女人有提到的男生nickname

    obj = models.UserInfo.objects.filter(id=4).first()
    result = obj.userinfo_set.all()
    for i in result:
        print(i.nickname)

其中,userinfo_set是将obj作为to_userinfo_id,查询任何的from_userinfo_id

FK自关联 (商量消息存储表)

采用于批评新闻存款和储蓄表

id news_id conent user reply_id
1 1 什么鬼 alex null
2 1 什么什么鬼 egon 1
3 1 sb eric 2
#models.py
class Comment(models.Model):
    news_id = models.IntegerField()
    conent = models.CharField(max_length=100)
    user = models.CharField(max_length=32)
    reply_id = models.ForeignKey('Comment', null=True, blank=True)

操作表

1.基本操作

views.py

def sql(request):
    from app01 import models

    # 增加数据
    models.UserGroup.objects.create(title="销售部")
    models.UserInfo.objects.create(username='root', password='123', age="20", ug_id=1)

    # 查询
    user_list = models.UserInfo.objects.all()  # 拿到QuerySet列表,其中存储的对像(一行就是一个对象)
    #models.UserInfo.objects.all().first()  # 取到QuerySet中的第一个对象
    group_list = models.UserGroup.objects.filter(id=1, title="销售部")  # 条件查询
    group_list = models.UserGroup.objects.filter(id__gt=1)  # id>1(_lt小于)
    print(user_list, group_list)
    for i in user_list:  # 显示字段
        print(i.username, i.age)

    # 删除
    models.UserInfo.objects.filter(id=2).delete()  # 删除

    # 更新
    models.UserInfo.objects.filter(id=1).update(title="人事部")  # 更新

    return HttpResponse("...")

2.进级操作

获得行数 .count()
models.UserInfo.objects.all().count()
比较 __gt
models.UserInfo.objects.filter(id__gt=1)  # id>1
models.UserInfo.objects.filter(id__gte=1)  # id>=1
models.UserInfo.objects.filter(id__lt=2)  # id<2
models.UserInfo.objects.filter(id__lte=2)  # id<=2
models.UserInfo.objects.filter(id__gte=1, id__lt=2)  # id>=1,id<2
in 和 not in
models.UserInfo.objects.filter(id__in=[1, 2, 4]) # 获取id在1,2,4中数据
models.UserInfo.objects.exclude(id__in=[1, 2, 4]) # 获取除id在1,2,4中的数据
isnull 为空

询问字段为空的数额 … where ut_id IS NULL

models.UserInfo.objects.filter(ut__isnull=True)
contains 字段内容包罗/不带有

字段是不是带有内容 … where name like ‘%a%’ /… where not (name like
‘%a%’ )

models.UserInfo.objects.filter(name__contains="a")
models.UserInfo.objects.filter(name__icontains="a")  # 大小写不敏感
models.UserInfo.objects.exclude(name__icontains="a") 
range 范围

bettwen … and …

models.UserInfo.objects.filter(id_range=[1, 3])
startswith/istartswith/endswith/iendswith

… where name like ‘a%’

models.UserInfo.objects.filter(name__startswith='a')
models.UserInfo.objects.filter(name__istartswith='a')
排序 order_by()
- 筛选结果按照id ASC排序
    models.UserInfo.objects.filter(id__gt=1).order_by("id")
- DESC排序
    models.UserInfo.objects.filter(id__gt=1).order_by("-id")

PS:order_by(“id”,”name”) 先按照id再按照name ASC排序

分组 annotate()
- import聚合函数
    from django.db.models import Count, Sum, Max, Min, Avg
- annotate()必须配合values(),values()中是要分组的列
    models.UserInfo.objects.values("ut_id").annotate(x=Count('id'))
    对应sql:
    "SELECT ut_id, COUNT(id) AS x FROM UserInfo GROUP BY ut_id"

PS:分组后结果再filter(),类似于group by后的having操作

models.UserInfo.objects.values("ut_id").annotate(x=Count('id')).filter(ut_id__gt=1)

相关文章

No Comments, Be The First!
近期评论
    功能
    网站地图xml地图