摘要:为了将代码规范,约定俗成将视图放置在项目或应用程序目录中命名为文件中。必须接受字段表示字符串长度不能超过该值,默认的标签最常用的。例,自动添加发布时间。以字符串的形式存在,默认最大长度,可以通过参数设置。用于保存通用唯一识别码的字段。
MVC
大部分开发语言中都有MVC框架
MVC框架的核心思想是:解耦
降低各功能模块之间的耦合性,方便变更,更容易重构代码,最大程度上实现代码的重用
m表示model,主要用于对数据库层的封装
v表示view,用于向用户展示结果
c表示controller,是核心,用于处理请求、获取数据、返回结果
MVT
Django是一款python的web开发框架
与MVC有所不同,属于MVT框架
m表示model,负责与数据库交互
v表示view,是核心,负责接收请求、获取数据、返回结果
t表示template,负责呈现内容到浏览器
客户端 -> 视图View -> 模型Model -> Mysql -> 模型Model -> 视图View -> 模版Template -> 视图View -> 客户端
Django环境安装:
pip install django==1.8.2
创建项目:
django-admin startproject test1
目录说明:
manage.py:一个命令行工具,可以使你用多种方式对Django项目进行交互-
内层的目录:项目的真正的Python包
_init _.py:一个空文件,它告诉Python这个目录应该被看做一个Python包
settings.py:项目的配置
urls.py:项目的URL声明
wsgi.py:项目与WSGI兼容的Web服务器入口
启动项目:
python manage.py runserver 8181
扩展项目目录
|-- app/ # 应用主目录 |-- templates/ # html 模板目录 |-- app/ |-- home.html # 主页html |-- login.html # 登陆页html |-- about.html # 关于页html |-- ... |-- static/ # 静态资源目录 |-- js/ # js资源目录 |-- lib/ # js library 资源目录 |-- page1/ # 页面1 js资源目录 |-- page2/ # 页面2 js资源目录 |-- ... |-- css/ # css资源目录 |-- images/ # 图片资源目录 |-- ... |-- admin.py # 配置模型models在django原生后台的管理 |-- apps.py # 应用级别的配置 |-- forms.py # 表单处理逻辑 |-- managers.py # 模型处理逻辑 |-- models.py # 模型定义 |-- urls.py # 路由设置 |-- views.py # 控制层 |-- tests.py
前后端项目分离
后端:
|-- app/ # 应用主目录 |-- admin.py # 配置模型models在django原生后台的管理 |-- apps.py # 应用级别的配置 |-- forms.py # 表单处理逻辑 |-- managers.py # 模型处理逻辑 |-- models.py # 模型定义 |-- urls.py # 路由设置 |-- views.py # 控制层 |-- tests.py
前端:
|-- src/ |-- app/ |-- home/ # 主页工作目录 |-- index.html # html 入口文件 |-- index.js # js 入口文件 |-- ... |-- login/ # 登陆页工作目录 |-- about/ # 关于页工作目录 |-- ...
Django有关命令
django安装:
pip install django==1.11.11 pip install -i yuan django=1.11.11
创建目录:
django-admin startproject filename
创建App:
python manage.py startapp appname
启动项目:
python manage.py runserver # 127.0.0.1:8000 python manage.py runserver 80 # 127.0.0.1:80 python manage.py runserver 0.0.0.0:80 # 0.0.0.0:80
数据库相关:
python manage.py makemigrations # 记录modules的变化,将变更的记录更新到 对应App下到migrations python manage.py migrate # 翻译成SQL语句,去数据库执行Django基础使用
app的概念:一个大项目中划分成很多功能模块
配置静态目录
# 在setting.py中, Static files (CSS, JavaScript, Images) STATIC_URL = "/static/" # alise STATIC_DIRS = [ os.path.join(BASE_DIR, "static"), ]
django基础三件套
from django.shortcuts import HttpResponse, render HttpResponse render redirect // 返回一条命令,浏览器再去请求重定向的地址
使用PY链接MySql
使用pymysql模块
导入pymysql模块
创建连接
获取执行命令的游标
用游标去执行SQL语句
获取SQL语句的执行结果
关闭游标
关闭连接
ORM
相似的数据,一类的数据放在同一张表中。具有相同属性,放在同一张表中。
ORM DB 类 数据表 属性 字段 对象 数据行
优点:开发效率高;不用直接写SQL语句;后端数据库变动,ORM适配。
缺点:执行效率低;SQL语句可能不是最优。
创建视图与ORM的app
不同的功能放在不同的包中
> python manage.py startapp appname
重新在使用的地方引入新的views的视图
在settings.py中重新配置,在字段INSTALL_APPS增加: app.apps.AppConfig
Django使用mysql
手动创建一个数据库create database djsite
配置Django连接数据库,可以使用多个数据库(读写分离,主从服务器)
DATABASES = { "default": { "ENGINE": "django.db.backends.mysql", "NAME": "djsite", "HOST": "127.0.0.1", "PROT": 3306, "USER": "root", "PASSWORD": "" } }
使用第三方的包连接数据库:pymysql, MySQLDb(支持py2),在djsite项目的__init__.py中告知Django使用pymysql
import pymysql pymysql.install_as_MySQLdb()
创建一张表,在app/models.py的文件中创建类
from django.db import models # Create your models here. class User(models.Model): id = models.AutoField(primary_key=True) # id 主键 email = models.CharField(max_length=32) # varchar(32) pwd = models.CharField(max_length=32) # varchar(32)
使用ORM
把models.py中变更的记录下来:python manage.py makemigrations
变更的记录创建成数据库语句执行:python manage.py migrate
视图中使用
User.objects.filter(emial=, pwd=) # 查询数据库中的字段
模版语言
展示:
{{name}}
for循环:
{%for item in press_list%}{%endfor%} {{forloop.counter}} {{item.id}} {{item.name}} 删除
配置settings.py
数据库相关配置:
ENGIGE # 引擎相关 mysql sqllite3 NAME # 数据库名字 HOST # IP PORT # 端口 3306 USER # 用户名 PASSWORD # 密码, ""
静态文件相关:
STATIC_URL = "static" # 别名 STATICFILE_DIRS = [ # 静态文件地址 os.path.join(BASE_DIR, "static") ]
APP:
INSTALL_APP = [ "app01.apps.App01Config" # 告知django新建了一个名叫app01的应用 # appName.appFile.appClass ]
ORM关系
class -> 数据表 object -> 行 attr -> 字段图书管理系统
表的设计
出版社 id, name 作者 id, name 书 id, title, 出版社_id(一对多,一本书只能选择一个出版社), 作者和书(多对多的关系,多一张关系表) id, 书_id, 作者_id
CURD
模型:
class Press(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32)
views.py中CURD操作:
def press_list(request): press_list = Press.objects.all().order_by("id") return render(request, "press_list.html", {"press_list": press_list}) def add_list(request): if request.method == "POST": press_name = request.POST.get("name") Press.objects.create(name=press_name) return redirect("/press_list/") return render(request, "add_list.html") def del_list(request): del_id = request.GET.get("id") Press.objects.filter(id=del_id).delete() return redirect("/press_list/") def edit_press(request): edit_id = request.POST.get("id") edit_press = Press.objects.get(id=edit_id) if request.method == "POST": new_name = request.POST.get("name") edit_press.name = new_name edit_press.save() # 注意保存 return redirect("/press_list/") return render(request, "edit_list.html", {"edit_item", edit_press})
ORM语句:
className.objects.all() className.filter() className.objects.get() className.objects.create(name="") className.objects.filter(id=id).delete() # 更改 obj = className.objects.get(id=id) obj.name = newName obj.save() # 注意保存
# 书籍表结构: # id, title, 关系字段(外键) create table_book( id int primary_key auto_increment, title varchar(30) not null press_id int not null, constraint fk_press foreign key(press_id) references press(id) on delete cascade update cascade )
ORM使用外键:
class Book(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(max_length=30) press = models.ForeignKey(to="Press", on_delete=models.CASCADE) # 外键, 关联Press表
外键查询:
book_obj.press # 书籍关联的出版社对象 book_obj.press_id # 数据库中实际存在的字段值
外键修改:
book_obj = Book.objects.create(title="", press=) book_obj = Book.objects.create(title="", press_id=)
ORM已经存在的表,再次更改字段,没有默认值,有必须填写,Django会提示手动输入默认值。
null=True default=默认值 price = Press.IntegerField(null=True) price = Press.IntegerField(default=100)
# 作者表,多对多结构: # SQL语句: create table author(id int primary_key auto_increment; name varchar(32) not null); create table authorToBook( id int primary_key auto_increment, author_id int not null, book_id int not null, constraint fk_author foreign key(author_id) references author(id) on delete on update cascade, constraint fk_book foreign key(book_id) references book(id) on delete on update cascade );
对多对的关系查询的使用
模型:
# ORM创建二张表: class Author(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) class AuthorToBook(models.Model): id = models.AutoField(primary_key=True) author = models.ForeignKey(to="Author", on_delete=models.CASCADE) book = models.ForeignKey(to="Book", on_delete=models.CASCADE) # Django中包含多对多的关系字段`ManyToManyField`: class Author(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) books = models.ManyToManyField(to="Book") # Django包含多对多字段
视图:
def author_list(request): author_data = Author.objects.all() # for item in author_data: # print(item.books.all()) # 连表查询,使用all()查询出数据来 return render(request, "author_list.html", {"author_data": author_data})
界面:
序号 | 作者id | 作者名字 | 作者作品 |
---|---|---|---|
{{forloop.counter}} | {{author.id}} | {{author.name}} | {% for book in data.books.all %} {% if forloop.last %} 《{{book.title}}》 {% else %} 《{{book.title}}》, {% endif %} {% empty %} 暂无作品 {% enfor %} |
查询多对多的关系字段:
author_obj.books.all()
修改:
author_obj.set(["book1", "book2"]) author_obj.add("book1", "book2", "book3")
清除:
author_obj.clear() # 清除对应关系
ORM操作
查:
from app01.models import User, Press, Book, Author Press.object.all() # 查询所有出版社对象(对象列表queryset) Press.object.filter(条件) # 查询所有满足条件的对象 Press.object.get(条件) # 查询有且只有一个对象 # 属性 press_obj.id press_obj.name # 外键属性 book_obj.id book_obj.press # 关联对象 book_obj.press.id # 多对多属性 author_obj.books # 管理对象 author_obj.books.all() # 作者关联的所有书籍对象
增:
from app01.models import User, Press, Book, Author new_press_obj = Press.object.create(name="") # 外键的增加 Book.object.create(title="", prece="", press_id=press_obj.id) Book.object.create(title="", prece="", press=press_obj) # 多对多关系的增加 new_author_obj = Author.object.create(name="") new_author_obj.books.set([press_id, press_id]) new_author_obj.books.set([book1, book2]) new_author_obj.books.add(book1, book2)
删:
book_obj.delete(条件) # 删除满足条件单个对象 Press.object.filter(条件).delete() # 删除满足条件的多个对象
改:
press_obj.name = "" press_obj.save() # 注意修改保存 Press.object.filter(条件).update() # 修改满足条件的多个对象 # 外键的修改 book_obj.press = press_obj book_obj.save() book_obj.press_id = press_obj.id # 多对多字段的修改 author_obj.name = "" author_obj.save() author_obj.books.set([press_id, press_id])
文件上传
f_dict = request.FILES.get("name") # 文件字典 print(f_dict) with open(f_dict, "wb") as f: for chunk in f_dict.chunk(): f.write(chunk)模版语言
变量相关:{{}}
逻辑相关:{% %}
点.在模版语言中,有特殊的含义,顺序为:
字典查询
属性或方法查询
数字索引查询
{{name}} {{dict1.name}} {{list1.0}}
模版语言中方法不用加()执行,Django自动调用,只能调用不带参数的方法。
filter
# {{变量名|方法|参数}} {{name|fun}} {{ value|add:"2" }} # 支持链式操作 {{ value|date:"D d M Y" }} {{ value|time:"H:i" }}
过滤器后加个冒号,再紧跟参数,中间不能有空格。
支持一个参数。
if语句支持过滤器, and, or, ==, <, >, in, !=, is, is not, not in, <=, >=
自定义filter
在app中新建一个templatetags包(名字固定,不能变,只能是这个),和views.py、models.py等文件处于同一级别目录下。这是一个包!不要忘记创建__init__.py文件以使得该目录可以作为Python的包。
在创建的包中,创建.py文件作为过滤器文件
from django import template # 生成注册实例 register = template.Library() @register.filter # 告知模版语言,自定义的filter def counter(val): """ counter :params {val} 管道符参数 :return {} """ return val + "counter"
在.html视图文件中导入,并使用。
# 导入filter模块 {% load counter %} # 使用该过滤器 {{ret|counter}}
需要重启django项目。
csrf
CSRF一般是POST请求:
{% csrf_token %}
标签;
使用POST的方法时,必须添加{% csrf_token %}标签,用于处理csrf安全机制;
{{ form }}代表Django为你生成其它所有的form标签元素,提交按钮需要手动添加;
母板与继承
# 子页面中继承父页面 {% extends "list/base.html" %} # 父级页面`base.html` {% block contenter %} {% endblock %} # 子页面 {% block contenter %} {% endblock %}
组件
# 引入组件 {% include "nav.html" %}
静态文件
{% load static %} {% load static %} {% get_static_prefix %} # 去settings.py中获取STATIC_URL的value值
自定义inclusion_tags
在app下创建一个templatetags的python包
在包下写py文件,mytags
编辑文件
from django import template register = template.Library()
定义函数,可以接收参数,需要返回字典
@register.include_tag(filename) # 组件名字 def pagination(total): return {"total": total}
在模版文件中使用字典参数,进行渲染
使用
{% load mytags %} { pagination 10 }Django中的视图
一个视图函数(类)称之为视图,它接受Web请求并且返回Web响应。
响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片。
无论视图本身包含什么逻辑,都要返回响应。为了将代码规范,约定俗成将视图放置在项目(project)或应用程序(app)目录中命名为view.py文件中。
FBV(Function Based View)
def login(request): # return HttpResponse("ok") # print(request.POST, "post") # print(request.Method, "method") # print(request.GET, "get") return render(request, "login.html", {"ret": "test"})
CBV(class Based View)
from django.views import View class AddPress(View): def get(self, request): return render(request, "add_press.html") def post(self, request): press_name = request.POST.get("name") Press.objects.create(name=press_name) return rediract("/press_list/")
在url.py中使用
url(r"/add_press/", views.AddPress.as_view())
流程:
views.AddPress.as_view()获取源码的view函数
当请求到来的时候执行view函数
实例化自己定义的类赋值给self
self = cls(**initkwargs)
self.request = request
执行父类中的self.dispatch(request, *args, **kwargs)
self.dispatch(request, *args, **kwargs)
判断请求方式是否被允许
handler = 允许的请求下通过**反射**获取自己定义的类中的`get`, `post`方法
不允许的情况下
handler = 不允许的情况, 父类中的http_method_not_allowed方法
执行handler方法
返回HttpResponse对象
把返回HttpResponse对象返回给Django
requset和response对对象:
requset对象:
["COOKIES", "FILES", "GET", "META", "POST", "body", "build_absolute_uri", "close", "content_params", "content_type", "csrf_processing_done", "encoding", "environ", "get_full_path", "get_host", "get_port", "get_raw_uri", "get_signed_cookie", "is_ajax", "is_secure", "method", "parse_file_upload", "path", "path_info", "read", "readline", "readlines", "resolver_match", "scheme", "session", "upload_handlers", "user", "xreadlines"]
requset常用的对象:
requset.method requset.GET requset.POST requset.FILES requset.COOKIES requset.path_info requset.body requset.scheme # 协议 requset.encoding # 编码 requset.META # 元数据 requset.get_host() # ip:host requset.is_ajax() # 是否是ajax请求
response对象:
from django.shortcuts import redner, HttpResponse, redirect HttpResponse("字符串") redner(requset, "xxx.html", {ret: ret}) redirect("跳转地址") # Location # 返回json数据,序列化 from django.http import JsonResponse def json_data(request): ret = {"name": "su", "age": 30} # return HttpResponse(json.dumps(ret)) # Content-Type: text/html charset=utf-8 return HttpResponse(json.dumps(ret), content_type: "application/json") return JsonResponse(ret) # Content-Type: application/json路由
URL是Web服务的入口,用户通过浏览器发送过来的任何请求,都是发送到一个制定的URL地址,然后被响应。
urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。
分组
url(r"^test/(d{4})/d{2}$", views.test) # test函数接收到正则匹配分组的参数
命名分组:
url(r"^test/(?Pd{4})/d{2}$", views.test) # test函数接收到正则匹配分组的year参数,也可以通过`args`或`**kwargs`来获取参数
视图默认参数
# URLconf from django.conf.urls import url from . import views urlpatterns = [ url(r"^blog/$", views.page), url(r"^blog/page(?P[0-9]+)/$", views.page), ] # View (in blog/views.py) def page(request, num="1"): # 当没有传递使用num=1 pass
路由转发
通常,在每个app里,各自创建一个urls.py路由模块, 然后从根路由出发,将app所属的url请求,全部转发相应的urls.py模块中。
项目目录的url.py下:
from django.conf.urls import include, url urlpatterns = [ url(r"^community/", include("app.aggregator.urls")), url(r"^contact/", include("app.contact.urls")), ]
app/aggregator/urls.py下:
from django.conf.urls import url from app import views urlpatterns = [ url(r"^test/", views.test) ]
地址栏访问方式:127.0.0.1:8000/app/test, test是app下定义的路由
命名URL和URL反向解析
命名:
url(r"press_list/", views.press_list, name="press_list") # 命名 url(r"^home/(d{4})/(d{2})/$", views.home, name=home) # 分组 url(r"^home/(?Pd{4})/(?P d{2})/$", views.home, name=home) # 命名分组
反向:
# 视图中应用 from django.shortcuts import redirect, reverse def press_list(): # reverse("press_list") -> /press_list/ redirect(reverse("press_list")) # url(r"^home/(d{4})/(d{2})/$") redirect(reverse("home", args=("2018", "12"))) # 分组,需要传递参数 "app/home/2018/12" # url(r"^home/(?Pd{4})/(?P d{2})/$", views.home, name=home) redirect(reverse("home", kwargs={"year": 2018, "month": 12})) # 命名分组
# 模版中应用 {% url "press_list" %} # 命名 {% url "home" "2018" "11" %} # 分组 {% url "home" year="2018" month="10" %} # 命名分组
命名空间 namespace
# urls url(r"^app01/", include("app01.urls", namespace="app01")) url(r"^app02/", include("app02.urls", namespace="app02"))
# 视图中使用 def home(request): reverse("app01:home") return HttpResponse("ok")
def delete(request, table, del_id): table_class = getattr(models, table.capitalize()) # getattr() 字符串映射到对象 table_class.objects.get(id=del_id).delete() return redirect(reverse(table)) # reverse 反向解析ORM
字段类型
类型 | 说明 |
---|---|
AutoField | 自增整数类型字段。Django会自动添加字段: `id = models.AutoField(primary_key=True),从1开始计数。主键 |
BooleanField | 布尔值类型。默认值是None。在HTML表单中表现为CheckboxInput标签,如果要接受null只,使用NullBooleanFiled |
CharField | 字符串类型。 必须接受字段max_length,表示字符串长度不能超过该值,默认的标签Input text,最常用的filed。 |
DateField | class DateField(auto_now=False, auto_now_add=False, **options)日期类型。一个Python中的datetime.date的实例。在HTML中表现为TextInput标签。Django会帮你自动添加一个JS的日历表和一个“Today”快捷方式,以及附加的日期合法性验证。两个重要参数:(参数互斥,不能共存) auto_now: 每当对象被保存时将字段设为当前日期,常用于保存最后修改时间。auto_now_add:每当对象被创建时,设为当前日期,常用于保存创建日期(注意,是不可修改的)。设置上面两个参数就相当于给field添加了editable=False和blank=True属性。如果想具有修改属性,请用default参数。例:pub_time = models.DateField(auto_now_add=True),自动添加发布时间。 |
EmailField | 邮箱类型,默认max_length最大长度254位。 |
FileField | class FileField(upload_to=None, max_length=100, **options)上传文件类型 |
ImageField | 图像类型 |
FilePathField | 文件路径信息。以字符串的形式存在,默认最大长度100,可以通过max_length参数设置。 |
IntegerField | 整数类型,最常用的字段之一。取值范围-2147483648到2147483647。在HTML中表现为NumberInput标签。 |
GenericIPAddressField | class GenericIPAddressField(protocol="both", unpack_ipv4=False, **options)[source]IPV4或者IPV6地址,字符串形式 |
TextField | 大量文本内容,在HTML中表现为Textarea标签 |
URLField | 一个用于保存URL地址的字符串类型,默认最大长度200。 |
UUIDField | 用于保存通用唯一识别码(Universally Unique Identifier)的字段。使用Python的UUID类 |
UUIDField: 需要设置default参数
import uuid from django.db import models def MyUUIDModel(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) # other filed
Meta配置
class UserInfo(models.Model): nid = models.AutoField(primary_key=True) username = models.CharField(max_length=32) # 表进行相关配置 class Mate: db_table = "table_name" # 数据库中生成的表名,默认:appname + 下划线 + 类名 verbose_name = "个人信息" # admin中显示的表名称 index_together = [ # 联合索引 ("pub_date", "deadline") # 应为两个存在的字段 ] unique_together = (("driver", "restaurant"),) # 联合唯一索引
查询数据的13个方法
django ORM操作
import os if __name__ == "__main__": os.environ.setdefault(‘DJANGO_SETTINGS_MODULE’, ‘project_name.settings’) # 设定配置文件 import django django.setup() from appname import models # 导入app中的模块 # all() 所有对象列表 # p = models.Person.objects.all() # get() 获取多个对象列表 # p = models.Person.objects.get(id=id) # 查询不到报错 # filter() 满足条件的对象列表 # p = models.Person.objects.filter(id=1) # exclude() 不满足条件的对象列表 # p = models.Person.objects.exclude() # values() # 取具体的数据的对象列表。 字典形式key: val # 没有指定参数,是所有的表的字段,可以制定某些字段。 # p = models.Person.objects.all().values() # p = models.Person.objects.all().values("id", "name") # values_list() # 取具体的数据的对象列表。元祖形式 val # 没有指定参数,是所有的表的字段,可以制定某些字段。 # p = models.Person.objects.all().values_list() # order_by() # 排序 # p = models.Person.objects.all().order_by("id") # p = models.Person.objects.all().order_by("-id") # 降序 # p = models.Person.objects.all().order_by("age", "id") # 多个字段排序 # reverse() # 反序 # p = models.Person.objects.all().order_by().reverse() # 需要进行排序后再反转 # distinct() # 去重 # count() # 统计 # p = models.Person.objects.all().count() # first(), last() # p = models.Person.objects.all().first() # p = models.Person.objects.filter().first() # exists() # 是否存在数据 # p = models.Person.objects.all().exists() print(p)
单表查询
import os import sys if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djsite.settings") import django django.setup() from app01 import models ret = models.Person.objects.filter(id__gt=1) # 大于 ret = models.Person.objects.filter(id__lt=4) # 小于 ret = models.Person.objects.filter(id__gte=1) # 大于等于 ret = models.Person.objects.filter(id__lte=1) # 小于等于 ret = models.Person.objects.filter(id__in=[1, 3]) # 小于等于 ret = models.Person.objects.filter(id__in=[1, 3]) # id=1, id=3 ret = models.Person.objects.filter(id__lt=1, id__gt=3) # 1 < x < 3 ret = models.Person.objects.filter(id__range=[1, 3]) ret = models.Person.objects.filter(name__contains="e") # name包含e,模糊查询 ret = models.Person.objects.filter(name__icontains="e") # name包含e,忽略大小写,模糊查询 ret = models.Person.objects.filter(name__startswith="e") # 开头包含e ret = models.Person.objects.filter(name__istartswith="e") # 开头包含e,忽略大小写 ret = models.Person.objects.filter(name__endswith="e") # 结尾包含e ret = models.Person.objects.filter(name__iendswith="e") # 结尾包含e,忽略大小写 ret = models.Person.objects.filter(birth_year=2018) # 2018年份 ret = models.Person.objects.filter(birth_month=12) # 12月份 ret = models.Person.objects.filter(birth_day=12) # 天数 print(ret, "ret")
外键查询
django终端打印SQL语句:
# 配置在`settings.py`中 LOGGING = { "version": 1, "disable_existing_loggers": False, "handlers": { "console":{ "level":"DEBUG", "class":"logging.StreamHandler", }, }, "loggers": { "django.db.backends": { "handlers": ["console"], "propagate": True, "level":"DEBUG", }, } }
#!/usr/bin/env python import os import sys if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djsite.settings") import django django.setup() from app import models book_obj = models.Book.objects.get(id=2) obj1 = models.Book.objects.filters(publisher__name="xxxx") # INNER JOIN 联表查询 obj2 = models.Book.objects.all().values("title", "publisher__name") # 表名__字段名
多对多的查询
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/41723.html
阅读 3401·2021-10-20 13:49
阅读 2762·2021-09-29 09:34
阅读 3656·2021-09-01 11:29
阅读 3057·2019-08-30 11:01
阅读 823·2019-08-29 17:10
阅读 838·2019-08-29 12:48
阅读 2760·2019-08-29 12:40
阅读 1303·2019-08-29 12:30