settings.py
INSTALLED_APPS = [
...
'app名.apps.App名Config', #新增这个,具体就是在app文件夹的apps.py里面的config对象,把这个路径放进来
]
js画图用,模板
https://echarts.apache.org/examples/zh/index.html#chart-type-line
conda activate django #激活django环境,django-admin就被加入到环境变量了
django-admin startproject 项目名
# 如:
(django) liuab@liuab-VirtualBox:~/django_project$ tree mysite
mysite
├── manage.py 【项目的管理,启动项目,创建app,数据管理】【不要动,但常用】
└── mysite
├── __init__.py
├── settings.py 【项目配置,如连接哪个数据库,注册app】 【经常修改】
├── urls.py 【url 和 python函数的对应关系】 【经常修改】
├── asgi.py 【接收网络请求,支持异步】 【不要动】
└── wsgi.py 【接收网络请求,支持同步】 【不要动】
django工程下的各个的小的应用程序
- 项目
- app,用户管理【表结构、函数、HTML模板,CSS】
- app,订单管理【表结构、函数、HTML模板,CSS】
...
我们开发较为简洁,用不到多app,项目下创建1个app即可
如何创建一个app:
python manage.py startapp app的名字
# 如:
python manage.py startapp app01
会在当前目录生成一个app
(django) liuab@liuab-VirtualBox:~/django_project/mysite$ tree .
├── app01
│ ├── __init__.py
│ ├── admin.py 不用动 为django默认提供的admin后台管理
│ ├── apps.py 不用动 app启动类
│ ├── migrations 不用动 数据库字段变更记录(自动生成)
│ │ └── __init__.py
│ ├── tests.py 不用动 单元测试
│ ├── models.py 【重要】,对数据库进行操作
│ └── views.py 【重要】,视图函数写在这里
├── manage.py
└── mysite
├── asgi.py
├── __init__.py
├── __pycache__
│ ├── __init__.cpython-38.pyc
│ └── settings.cpython-38.pyc
├── settings.py
├── urls.py 【url->函数,调用的函数在views编写】
└── wsgi.py
确保 app 已注册 【settings.py】
将 app01 文件夹下的 apps.py 文件中的 App01Config
类,写在 mysite 中的 settings.py 中的 INSTALLED_APPS
列表里
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config', #新增这个
]
编写 url 和 视图函数的对应关系 【urls.py】
from app01 import views
urlpatterns = [
# path('admin/', admin.site.urls),
# 该句意思是,当有用户访问 www.xxx.com/index/ 时,会调用 app01/views文件中的index函数
path('index/', views.index),
]
编写 views 函数
from django.shortcuts import render, HttpResponse
def index(request): # 默认需要参数request
return HttpResponse("欢迎使用")
启动django项目
python manage.py runserver
urls.py再加一个,views里面再写一个就可以了。
在你的app内创建templates
文件夹,里面用于放html文件
def return_html(request):
return render(request,"aaaa.html")
# 寻找html会按照app的注册顺序,去相应的文件夹下的templates文件夹下寻找html
图片,css,js都会当作静态文件处理
静态文件也不能乱放,要放在app下的static文件夹中
记得在static文件夹下,创建 img, css, js 这三个用于放置静态文件的文件夹
引用方式一:就是html 的这种方式,但不推荐
引用方式二:
html中
{% load static %} #开头加上这个
<body>
<img src="{% static 'img/aaa.png' %}" alt="">
body>
方式二有提示,比较好,而且以后可以在settings.py文件中更改 STATIC_URL。
这样如果static文件位置移动后,只要改STATIC_URL就可以对html中引用的静态文件路径同意更改了。
django独有的。
具体流程
用户传参数给url,找到对应的view函数
view函数的render 以 字符串 读取了 ”带有django模板语法“的 html文件到内存 ,并根据view函数中传入的参数 ,对html文件进行渲染(将模板语法执行并替换,替换内容,for循环替换成多个语句,等等,基本就是替换内容),然后得到一个 只包含html的字符串,继而将其返回给用户浏览器
即 用户的浏览器不可能读到模板语法的
html中 {{ param }} 是直接显示传入的参数
但如果没有从render传param这个值,则不显示,传了才显示,可以用作显示用户名或密码错误 再定向到当前页面时传一个错误信息
{{param}} 可以红色显示
def return_html(request):
return render(request,"aaaa.html")
# 寻找html会按照app的注册顺序,去相应的文件夹下的templates文件夹下寻找html
请求
这里的 request
是一个对象,封装了用户通过浏览器发送过来的所有数据
其有多个属性:
请求方式 request.method
get或post
接收get请求携带的参数 request.GET
比如,www.xxx.com/?param1=123¶m2=234
print(request.GET) 就能将其输出 QueryDist对象
接收post请求(请求体)携带的参数 request.POST
QueryDist对象,就可以和一般的dist字典用 .get("key_name")
得到value
响应
return的东西
注意:
post请求 要在html的form表单中 添加 {% csrf_token %}
,否则会报403的错误
(添加了 {% csrf_token %}
之后,提交时会顺当隐含提交一个csrf_token,用于 django 校验请求是不是正常网页发送的,不是的就403)
ORM框架,可以以pymysql mysqldb mysqlclinet 为backend为底层 与数据库进行操作
ORM对我们来说写的代码会更方便更简洁一些
教程 https://pypi.org/project/mysqlclient/#fies
linux:
Note that this is a basic step. I can not support complete step for build for all environment. If you can see some error, you
should fix it by yourself, or ask for support in some user forum. Don’t file a issue on the issue tracker.
You may need to install the Python 3 and MySQL development headers and libraries like so:
$ sudo apt-get install python3-dev default-libmysqlclient-dev build-essential # Debian / Ubuntu
Then you can install mysqlclient via pip now:
$ pip install mysqlclient
记得还要安装mysql服务器
sudo apt-get install mysql-server
ORM 可以帮我们做两件事
net start mysql
mysql -uroot -p密码
create database 数据库名 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
show databases; # 查看创建的数据库
在settings.py
中配置修改,将DATABASES替换为:
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': BASE_DIR / 'db.sqlite3',
# }
# }
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'rPPG', # 数据库名称
'USER': 'root',
'PASSWORD': 'asd',
'HOST': '', # 哪台机器安装的mysql,留空默认localhost
'PORT': '3306',
}
}
创建表
首先确定 app 已注册。
在 app 的 models.py 中 写一个类继承 models.Model
类
# Create your models here.
class UserInfo(models.Model):
name = models.CharField(max_length=32)
password = models.CharField(max_length=64)
age = models.IntegerField()
"""
相当于在mysql中
create table app01_userinfo(
id bigint auto_increment primary key,
name varchar(32),
password varchar(64),
age int
)
"""
在终端执行命令
python manage.py makemigrations
python manage.py migrate
执行完后,进入mysql
use 数据库名;
show tables;
+----------------------------+
| Tables_in_rPPG |
+----------------------------+
| app01_userinfo |
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions | 其他的表不用管
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+----------------------------+
11 rows in set (0.00 sec)
可以拿到刚才创建的 app01_userinfo
(app名+类名)
desc app01_userinfo;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | bigint | NO | PRI | NULL | auto_increment | id就是第几个数据 从1开始
| name | varchar(32) | NO | | NULL | |
| password | varchar(64) | NO | | NULL | |
| age | int | NO | | NULL | |
+----------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
表就创建好了。
增删改表属性
新增一列时,修改class
class UserInfo(models.Model):
name = models.CharField(max_length=32)
password = models.CharField(max_length=64)
age = models.IntegerField()
height = models.FloatField(null=True,blank=True) # 新增
weight = models.FloatField(default=2) # 新增
若原始表中已有数据,新增属性时,对已有数据的行的该属性存疑,可通过default参数设置默认值,也可以null=True,blank=True允许为空(更常用)
以后想要再修改表时
只需在models.py中操作类(增删改),
然后执行
python manage.py makemigrations
python manage.py migrate
即可。
desc app01.userinfo 查看表结构
对于这样一个类:
class UserInfo(models.Model):
name = models.CharField(max_length=32)
password = models.CharField(max_length=64)
age = models.IntegerField()
新增数据(增):
# 新增一行数据
UserInfo.objects.create(name="张三", password="333", age=18)
# 如果有参数没写,则按照类中属性的默认(default值 或 null,需要自己在类中设置好)
(查看某表数据的方式,在mysql中 select * from app01_userinfo(表名)
)
删除数据(删):
UserInfo.objects.filter(name="张三").delete() # filter是根据条件筛选,里面可以是任一属性,包括id
UserInfo.objects.all().delete() # 删除所有数据
获取数据(查):
UserInfo.objects.all() # 全部获取
# 获取表中的所有数据,为QuerySet类型,理解为一个列表,
# 列表中是一行一行的数据,每一行数据为一个封装好的对象
# 如果想要获取对各对象的数据,直接用对象调用属性的方式调用即可。
data_list = UserInfo.objects.all()
for obj in data_list:
print(obj.id, obj,name, obj.password)
UserInfo.objects.filter(id=1) # 筛选,筛选出来的也是个列表queryset,就算只有一行数据,也是一个只包含一个对象的列表
UserInfo.objects.filter(id=1).first() #直接取出第一个对象
修改数据(改):
UserInfo.objects.all().update(password='asdasdasd') # 一个例子,应该就会用了
...
# 用户管理
path('info_list/',views.info_list)
...
def info_list(request):
data_list = UserInfo.objects.all() # 获取数据库中所有的用户信息
return render(request,"info_list.html",{"data_list":data_list}) # 返回一个页面
...
<body>
<h1>Info 列表h1>
<table border="1">
<thead>
<tr>
<th>IDth>
<th>姓名th>
<th>年纪th>
tr>
thead>
<tbody>
{% for obj in data_list %}
<tr>
<td>{{ obj.id }}td>
<td>{{ obj.name }}td>
<td>{{ obj.age }}td>
tr>
{% endfor %}
tbody>
table>
body>
...
url.py
...
path('info_add/',views.info_add)
views.py
...
def info_add(request):
if request.method == "GET": # GET请求(直接通过 url 访问)
return render(request,"info_add.html") # 返回一个页面
# 否则为 POST请求
# 获取用户提交的信息
name = request.POST.get("name")
age = request.POST.get("age")
# 添加到数据库
UserInfo.objects.create(name=name, age=age)
return render(request,"info_add.html") # 仍返回该页面
info_add.html
...
<body>
<h1>添加用户h1>
<form method="post" action="/info_add/">
{% csrf_token %}
<input type="text" name="name" placeholder="请输入名称">
<input type="text" name="age" placeholder="请输入年龄">
<input type="submit" value="提交">
form>
body>
...