Django记录
一. APP
Django 中的一个app 就是项目里面的一个应用的意思。
一个项目包含多个app。
一个app 通常就是一个相对独立的模块 ,实现相对独立的功能
一个app 本质上 就是一个 Python 包 .py 文件
二. 创建django项目,app,启动
python manage.py startproject cccc
python manage.py startapp sales
python manage.py runserver
三. ORM 增.删.改.查
1.增加
方式一: 表名.objects.create
record = Book.objects.create(title="人类简史2")
record代表一条记录,
record.id 可以直接取到id字段的值
方式二,
修改的时候
model对象.save()。
2.删除
方法一:
delete只能跟在filter之后。
Book.objects.filter(title="大明帝国").delete()
方法二:
# 根据id 从数据库中获取相应的客户记录
try:
customer = Customer.objects.get(id=customer_id)
except Customer.DoesNOtExist:
return JsonResponse({'msg': '不存在'})
customer.delete()
3.修改
更新update 必须在filter()之后
recordinfo.objects.filter(user_id=userid).update(surplus_point=point,)
4.Q查询 【好用】
QuerySet对象:每条表记录都是一个dict对象{‘key’: ‘value’}
qs = Customer.objects.values()
#返回一个QuerySet对象,包含表的所有记录
retlist = list(qs)
# 将QuerySet对象 转换为 list类型,否则不能被转换为就送字符串
通常情况下,我们使用的filter(条件1,条件2,…),执行的都是and查询。
但是通常一些时候,我们需要执行or查询。
比如book表,查询title=<<大明帝国>> or title=<<安史之乱>>的。
这时候,如果使用Django ORM,就只能使用Q查询构建条件。
from django.db.models import Q
books = models.Book.objects.filter(Q(title="<<大明帝国>>") | Q(title="<<安史之乱>>"))
5.F查询
有时候,我们可能有这样的需求,就是两个列之间进行比较。
比如经典问题,一个商品,找到收藏数大于销量的商品等之类的两列进行比较的需求。
示例:查询book表,评论数小于收藏数的数据。
from django.db.models import F
book = models.Book.objects.filter(comment_num__lt=F("collect_num"))
print(book)
6.F对象还适用于更新
代码
models.Book.objects.all().update(price=F("price")+30)
F的用法是F('字段名'),F()是用来取值的。
7. 正向操作-- 关联表
- 通过对象访问外键表
【过主表 访问 外键所在表的值】
s1 = Student.objects.get(name = '白月')
#获取了name=白月的实例, s1就是一个学生类的具体对象
s1.country : Country object(1) 返回一个country对象
s1.country.name : 中国 返回具体值
- 根据外键表过滤
查找student表中 所有一年级 + 中国 学生
方法一: 先获取中国国家的id, 然后再通过id去找一年级的学生
cn = Country.objects.get(name='中国')
Student.objects.filter(grade=1, country_id = cn.id).values()
注意外键字段的id是通过后缀 _id获取
缺点:两条数据请求,性能不高
方法二:
Student.objects.filter(grade=1, country__name='中国').values()
__两个下划线!!
只要反回名字,国家名
Student.objects.filter(grade=1, country__name='中国').values('name', 'country__name')
把country__name改一下名(annotate():
from django.db import F
Student.objects.annotate(countryname = F('countr__name'), studentname=F('name')).
filter(grade=1, country__name='中国').values('name', 'country__name')
8. 反向操作-- 关联表
如果你已经获取了一个Country对象,如何访问所有属于这个国家的学生?
方法一:
cn = Country.objects.get('name' = '中国')
cn.student_set.all()
cn.student_set.all()[0] : Student object(1) 学生对象
cn.student_set.all()[0].name : '白月'
通过 表**Model名转化为小写, 后面加一个-set** 来获取所有的反向外键关联对象
方法二:
在定义Model时候,外键字段使用 related_name参数
9. 去重 .distinct()
四. request对象
from django.http import HttpResponse
def listorders(request):
return HttpResponse("下面是系统中所有的订单信息。。。")
listorders的参数request是Django中的 HttpQuest对象,包含了请求中的信息。
五. 路由 urls
-
在项目的同名主目录下的urls.py 是url路由设置的入口文件【主路由】
-
实现url 分类,拆分
一级路由:在sales文件下新增 urls.py
from django.url import path, include
凡是以sales开头的url,
就去sales下的urls.py中去查询
path('sales/', include('sales.urls'))
- 路由可以 正则 匹配
path不支持正则匹配
语法:path(‘URL/’,app01视图文件views.视图中执行的函数)
六. 数据库配置[mysql, sqlite]
1、mysql 设置 在项目同名包下的_init_.py里面添加
# DJango 使用mysql
import pymysql
pymysql.install_as_MySQLdb()
或者
import pymysql
pymysql.version_info = (1, 3, 13, "final", 0)
pymysql.install_as_MySQLdb()
2、项目同名包下的 setting.py里修改Database
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 数据库类型
'NAME': 'test', # 数据库名字
'USER': 'root', # 服务器用户名
'PASSWORD': '123456', # 密码
'HOST': 'localhost',
'PORT': '3306'
}
}
- 使用sqlite3数据库时
若原来没有db.sqlite3这个文件
只需要执行:
python manage.py migrate
就会在项目根目录下生成一个配置文件中指定的数据库文件,并在当前文件中创建一些Django自带的表
工具:**sqlitestudio**
- 创建数据库表
from django.db import models
class Customer(models.Model):
name = models.CharField(max_length=200)
phonenumber = models.CharField(max_length=200)
数据类型官方文档:
CharFlield https://docs.djangoproject.com/en/2.0/ref/models/fields/#model-field-types
在数据库中创建表
- 首先 告诉Django 我们在models模块中定义了一个新数据表
在settings.py 中的 INSTALLED_APP中 增加应用
'common.apps.CommonConfig'
common: app名字
apps: common文件下的 apps.py文件
CommonConfig: apps.py文件下的CommonConfig类
- 检查Django下的common应用 中的models有没有更新
python manage.py makemigrations common
一但修改表定义时, 就要执行本代码
- 真正将本次变动提交到数据库
python manage.py migrate
-
DJango中每张表都应该有主键字段,若没有定义,则自动加上一个id字段作为主键
通常我们都让他自动生成id -
若在已经创建好的字段中新增一个字段,则必须加缺省值,或者允许为空
null = True , blank=True 允许空值,空字符串
- 在数据库中新增管理员账号
python manage.py createsuperuser
- 在admin界面中展示数据库表
在/modes.py 下的Customer类下增加 :
from django.contrib import admin
admin.site.register(Customer)
表定义:一对多
订单表中的客户,必须是客户表中的某条记录
一个客户下可有多个订单‘’
在数据库中用外键来表示
如果一个表中某个字段是外键, 那就意味着这个外键的字段的记录的取值,只能是他关联表的主键某个记录的值
customer = models.Foreignkry(Customer, on_delete=models.PPROTECT)
关联主键外键表 Cudtomer :是客户表
on_delete=models.PPROTECT
当主键表中删除某条记录时,外键就没有相对应的主键记录
on_delete判断此时该如何处理
on_delete=models.Cased :删除主键相关 删除相关的全部表记录
表定义 :一对一
例:学生表 和学生地址表
用户表和ip余额表
DJango中用 OneToOneField对象实现 一对一的关系
student = models.OneToOneField(Student, on_delete=models.PROTECT)
表定义: 多对多
medicines = models.ManyToManyFileld(Medicinem, ' ')
七. 模板
1. 模板for 循环
{% for customer in customers %}
<tr>
{% for name, value in customer.items %}
<td> {{ value }}</td>
{% endfor %}
{% endfor %}
from
八. session 和token
session 方案 的原理如下:
服务端在数据库中保存一张session表。 这张表记录了一次用户登录的相关信息。
具体记录什么信息, 不同的系统各有差异, 通常 会记录 该用户的 ID 、姓名 、登录名 之类的。
在session表中增加记录:
request.session['usertype'] = 'mgr'
服务端接受到该请求后,只需要到session表中查看是否有该 sessionid 对应的记录,这样就可以判断这个请求是否是前面已经登录的用户发出的。
如果不是,就可以拒绝服务,重定向http请求到登录页面让用户登录。
九. 宝塔启动DJango
1、安装Centos系统
2、登录命令界面:安装宝塔
centos安装宝塔命令:
yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh ecc2a9
3、登录宝塔, 软件商店安装:python项目管理器、mysql、nigx
4、在文件/www/wwwroot/下导入打包好的DJango包
5、软件商店/python项目管理器/ 安装python3.68
6、项目管理/新建项目
7、服务器开启8000端口
ALLOWED_HOSTS=["*", ]
接下来我们需要设置防火墙,开放8000端口。注意下述操作需要管理员权限。
查看所有开放的端口:
firewall-cmd --zone=public --list-ports
如没有8000端口,则将8000端口永久开放:
firewall-cmd --zone=public --add-port=8000/tcp --permanent
重新加载配置信息:
firewall-cmd --reload
一切就绪,此时从其他电脑就可以访问此Django服务器了。
十、django跨域
第一步,安装第三方扩展:
pip install django-cors-headers
第二步,添加应用:
INSTALLED_APPS = (
...
'corsheaders',
...
)
第三步,中间件处理,注意放在第一条,第一时间进行处理:
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]
第四步,配置访问规则或白名单:
#允许所有域名跨域(优先选择)
CORS_ORIGIN_ALLOW_ALL = True
# 或配置白名单:
# CORS_ORIGIN_WHITELIST = (
# '*'
# # '127.0.0.1:8000',
# # 'localhost:8000',
# # '127.0.0.1:8080',
# # 'localhost:8080',
# # 'ads-cms-api.aataotao.com:8000' #
# # 'taoduoduo-test.oss-cn-shenzhen.aliyuncs.com:80', # 线上
# # '10.0.2.187:8080' # 本地
# )
第五步,允许携带cookie:
CORS_ALLOW_CREDENTIALS = True
注意一个重要问题:
如果使用了nginx,注意正确配置.
sudo vim /usr/local/nginx/conf/nginx.conf
location / {
proxy_pass 127.0.0.1:8000/;
}