文章目录
0.第一次使用
写一个简单的登入注册功能。
文件
链接:https://pan.baidu.com/s/1ILTL5iPHQp1rR1KfR_i7-A
提取码:aej1
1.静态文件配置
静态文件:前端写好的能直接使用的文件。
1. 网站写好的js文件
2. 网站需要用到的css文件
3. 网站用带的图片文件
4. 第三方前端框架
5. 其他可以拿来就直接使用的文件。
1.1文件位置
html文件默认都放在templates文件下。
站所有的静态文件都放在staric文件夹下,
需要自己手动创建文件static文件(别人都使用这个名称,就约定俗成了)。
对static文件夹进一步的划分处理,目的就是解耦合。
static
js
css
img
其他第三方文件
2.简单的登入页面
2.1创建项目
新建项目 --> Django项目 --> 创建
mysize文件夹
|--mysize文件下
|--__init__.py
|--settings.py 配置文件
|--urls.py 路由与视图关系文件
|--wsgi.ps
|--templates 存放html文件
|--static 手动创建,存放静态文件
2.2建立关系
1.创建app01应用
一个程序必须有一个应用。
在pycharm底部打开终端:
输入:
python manage.py startapp app02
2.注册app引用
创建的app必须要注册,在settings配置文件中添加注册。
INSTALLED_APPS = [
'django.contrib.admin',
····························
'app02' # 添加app应用名称
]
3.分析需求
在地址栏输入127.0.0.1/login/
返回一个网址
4.在urls.py
在urls.py中建立关系。
from django.conf.urls import url
from django.contrib import admin
from app01 import views # 添加创建的app应用
urlpatterns = [
url(r'^admin/', admin.site.urls),
# 登入功能的路由与视图关系
url(r'^login/', views.login)
]
5.写功能
打开app02应用的views.py写功能。
# 所有自定义的函数都需要写request形参。
def login(request):
# 返回一个html页面
return render(request, 'login.html')
6.返回的网页
网页的地址在templates文件中。
将样式文件bootstrap-3.3.7-dist复制到static文件下。
templates下的创建login.html文件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
<h1 class="text-center">登入</h1>
</body>
</html>
如果运行出错找不文件路径,在settings中将原本的'DIRS'的配置替换。将template的路径添加到环境变量中的设置更改一个。
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
···
7.路径开发
在浏览器输入url能够看到对应的资源,是因为后端开设了该资源的接口,
如果访问不到资源,说名后端没有开始该资源的接口。
settings.py文件下:
STATIC_URL = '/static/' 相当于令牌,访问的路径必须以这个令牌的名称开始。
令牌名字更改了所有相关的路径都需要手动改。
/xxx/
os.path.join(BASE_DIR, 'xxx')
文件中的名称也需要一起改:
/xxx/bootstrap-3.3.7-dist/js/bootstrap.min.js
8.静态文件配置
settings.py文件下的STATIC_URL = '/static/' 下方, 静态文件路径配置。
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
os.path.join(BASE_DIR, 'static1')
]
取值列表从上玩下依次查找,都没有则报错。
/static/bootstrap-3.3.7-dist/js/bootstrap.min.js
建立一个static1的文件件,再新建一个文件1.txt写 hello word!
访问
http://127.0.0.1:8000/static/1.txt
验证取值列表从上玩下依次查找的。
在写django项目的时候可能会出现后端代码修改了前端页面没有变化:
1.在用一个端口开了好几个django项目,一直运行的还是第一个gjango项目
2.流浪器缓存的问题
settins (检测 - f1)
netword
勾选disable xxxxx
刷新
3.就是你代码有问题。

10动态修改
令牌名字更改了所有相关的路径都自动改。
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js'%}"></script>
11.访问

3.request对象方法
request对象:请求相关的数据对象,里面有很多简易的方法。
3.1例
修改login.html文件内容。
访问下127.0.0.1/login
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js'%}"></script>
</head>
<body>
<h1 class="text-center">登入</h1>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form action="">
<p>username: <input type="text" name="username" class="form-control"></p>
<p>password: <input type="text" name="password" class="form-control"></p>
<p>hobby
<input type="checkbox" name="hobby" value="1"> 1
<input type="checkbox" name="hobby" value="2"> 2
</p>
<input type="submit" class="btn btn-success btn-block">
</form>
</div>
</div>
</div>
</body>
</html>

1.查看请求方式
request.method 返回请求方式,返回值为大写的字符串(GET/POST)。
修改app01下views.py文件。
def login(request):
print(request.method)
return render(request, 'login.html')
GET
2.from表单提交数据
from表单默认是get方式提交。
get请求携带数据有大小的限制,大概4kb左右。
而post没有限制。
action的三种情况:
1.不写,默认朝当前所有url提交数据。
2.全写,指定详细位置。
3.指定后缀/login/
修改app01下views.py文件。
from django.shortcuts import render
def login(request):
print(request.method) # 打印当前提交方式,默认为get。
return render(request, 'login.html')
在表单写数据
username:kid
password:123
勾选1和2
点登入

[11/Aug/2021 16:46:06] "GET /login/ HTTP/1.1" 200 998
GET # 第一个gat 是请求
[11/Aug/2021 16:46:17] "GET /login/?username=kid&password=123&hobby=1&hobby=2 HTTP/1.1" 200 998
GET # 第二个是form表单的提交方式
修改from表单的提交方式为post,再次访问,提交数据。
<form action="" method="post">
[11/Aug/2021 17:06:27] "GET /login/ HTTP/1.1" 200 1012
GET # 第一个gat 是请求
[11/Aug/2021 17:06:36] "POST /login/ HTTP/1.1" 200 1012
POST # 第二个是form表单的提交方式
3.获取post请求数据
修改form提交方式。
<form action="" method="post">
在使用django提交post请求的时候需要在配置中注释掉,否则报错 403.
settings中
MIDDLEWARE =[
···
# 'django.middleware.csrf.CsrfViewMiddleware'
···
]
request.POST:获取用户提交的post请求数据(不包含文件),是一个字典的形式。
request.POST.get('xxx') : 通过get取值,如果有多个值,取最后一个值。
request.POST.getlist('hobby'):如果有多个值,取多个值为列表形式。
from django.shortcuts import render
def login(request):
if request.method == 'POST':
print(request.POST)
print(request.POST.get('username'))
print(request.POST.get('password'))
print(request.POST.get('hobby'))
print(request.POST.getlist('hobby'))
return render(request, 'login.html')
<QueryDict: {'username': ['kid'], 'password': ['123'], 'hobby': ['1', '2']}>
kid
123
2
['1', '2']
4.获取get请求数据
request.GET:获取用户提交的post请求数据(不包含文件),是一个字典的形式。
request.GET.get('xxx') : 通过get取值,如果有多个值,取最后一个值。
request.GET.getlist('hobby'):如果有多个值,取多个值为列表形式。
<form action="" method="get">
from django.shortcuts import render
def login(request):
"""
get请求于post请求因该有不同的处理机制
:param request:请求相关的数据对象,里面有很多简易的方法
"""
if request.method == 'POST':
print(request.POST)
print(request.POST.get('username'))
print(request.POST.get('password'))
print(request.POST.get('hobby'))
print(request.POST.getlist('hobby'))
# 第一次get请求是没有值的,点击按钮提交from表单,填了则有值否则就空字符串。
if len(request.GET) != 0:
print(request.GET)
print(request.GET.get('username'))
print(request.GET.get('password'))
print(request.GET.get('hobby'))
print(request.GET.getlist('hobby'))
return render(request, 'login.html')
有值和POST的情况一样,提交空表的情况:
<QueryDict: {'username': [''], 'password': ['']}>
None
None
None
[]
4.pycharm连接数据库
pycharm中三个位置查找数据库:
1.右侧上面 darabase。
2.左侧下面 database。
3.配置里面的plugins插件搜索darabase安装。
pycharm可以充当很多款数据库软件的客户端。
第一个选择数据库后记得下载驱动。
1.选择数据库

2.安装驱动
点DOwnload

3.设置通信信息
填好了先点Test ** 测试先是否能成功连通,
连接的库必须是提前建立好的。

]
4.创建库
使用Navicat创建
https://blog.csdn.net/qq_46137324/article/details/119303398
命令行创建
https://blog.csdn.net/qq_46137324/article/details/119150449
5.测试成功点ok

6.查看数据库

5.django连接数据库
django 自带一个 sqkite3数据库。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
将默认的库修改为MySQL。
第一步:settings配置文件修改:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db1',
'USER': 'root',
'PASSWORD': 123,
'HOST': '127.0.0.1',
'POST': 3306,
'CHARSET': 'utf8' # 不能使用-
}
}
第二步:代码声明
django 默认是使用mysqldb模块连接MySQL,但该模块的兼容性不好,需要手动改为pymysql模块链接。
替换模块,使用pymysql。
安装 pip3 install pymysql
在app01应用下有个__init__,或者任何应用名下书写以下代码
import pymysql
pymysql.install_as_MySQLdb()
6.Django ORM
作用能够让一个不会用sql语句的小白也能通过python面向对象的代码简单快捷的操作数据路。
不足之处:封装程度太高,有时候效率低,需要自己写sql语句。
ORM对象关系映射:
类 ---> 表
对象 ---> 记录
对象属性 ---> 记录中的某个字段
6.1创建表
1.第一步models.py中创建表
app应用下面的models.py创建表
models.py中书写一个类就是创建一个表。
类必须继承models.Model才能创建。
# 创建表
class user(models.Model):
# 添加字段
# verbose_name 参数是字段的解释信息
id = models.AutoField(primary_key=True, verbose_name="主键")
username = models.CharField(max_length=32,verbose_name="密码")
password = models.IntegerField()
id = models.AutoField(primary_key=True, verbose_name="主键")
等同于
id int primary_key auto_increment
username = models.CharField(max_length=32, verbose_name="用户名")
等同于
username = models.CharField(max_length=32,verbose_name="密码")
varchar字段必须指定max_length参数不指定就会直接报错。
password = models.IntegerField()
等同于
password int
2.第二步:数据库迁移命令
需要迁移数据库才能生效
1. python manage.py makemigrations
(简写,运行task的 run manage task,直接输入makemigrations)
将操作记录记录在migrations文件夹中migrations文件夹中默认只有一个__init__.py,
执行命令后,会多一个文件,会记录操作。
2. python manage.py migrate
将操作真正的同步到数据库中。
***** 只要修改了models.py中的更数据库相关的代码就必须重新执行上面的代码。*****
无法迁移,检查app是否注册。
INSTALLED_APPS = [
···
'app02.apps.App01Config',
]

orm创建的表会自动加上一个前缀,应为一个django项目有很多的应用,多个应用之间可能出现表名的冲突,加上前缀来避免冲突。
6.2自动添加id字段
每个表中都需要有一个主键字段,并在一般情况下都叫id字段,
在没有定义id字段时,orm会自动创建一个名为id的主键字段。
class Author(models.Model):
username = models.CharField(max_length=32)
password = models.IntegerField()
后续在创建模型表的售后如果主键字段名没有而外的叫法,那么主键字段可以省略不写。
6.3字段操作
1.字段增加
lv = models.IntegerField()
数据库迁移命令xxx
You are trying to add a non-nullable field 'age' to user without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Quit, and let me add a default in models.py
Select an option:
添加空的键需要值,1提供值2退出
1 1 回车
2 exit 回车
E:\备份\test\djangoProject1>python manage.py makemigrations
You are trying to add a non-nullable field 'lv' to user without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Quit, and let me add a default in models.py
Select an option: 1
Please enter the default value now, as valid Python
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now
Type 'exit' to exit this prompt
>>> 6
Migrations for 'app02':
app02\migrations\0002_user_lv.py
- Add field lv to user
E:\备份\test\djangoProject1>python manage.py migrate
System check identified some issues:
WARNINGS:
?: (mysql.W002) MySQL Strict Mode is not set for database connection 'default'
HINT: MySQL's Strict Mode fixes many data integrity problems in MySQL, such as data truncation upon insertion, by escalating warnings into errors. It is strongly recommended you activate it. See: https://docs.djangoproject.c
om/en/1.11/ref/databases/#mysql-sql-mode
Operations to perform:
Apply all migrations: admin, app02, auth, contenttypes, sessions
Running migrations:
Applying app02.0002_user_lv... OK
第一钟情况,在终端输入值 1, 添加的字段的值都为1
lv = models.IntegerField(validators='1')
第二种情况 设置null为空,添加的字段全部为空
info = models.CharField(max_length=32, verbose_name='简历', null=True)
第三情况,这种默认值,添加的字段全部为默认的值
hobby = models.CharField(max_length=32, verbose_name='爱好', default='study')
修改后需要一定要执行
python manage.py makemigrtions
python manage.pu migrate
2.字段的更改
直接修改代码
password = models.CharField(max_length=30, validators='密码')
迁移命令xxx
3.字段的删除
将需要删除的字段注释掉
# lv = models.IntegerField()
# info = models.CharField(max_length=32, verbose_name='简历', null=True)
python manage.py makemigrtions
python manage.pu migrate
直接注释的后对应的数据会全部丢失。
不要轻易的操作删除字段。操作迁移命令的时候一定要检查自己写的代码。
4.字段的查肉眼看
以后在补上、
6.4数据的增删改查
先在Navicat为app02_user添加数据:
id username password
1 kid 123
2 qz 456
models.user.objects.filter(查询条件).first()
models.User.objects.create(username=username, password=password) 添加数据
models.User.objects.filter(id=edit_id).update(更改的字段=值,更改的字段=值) 改
models.User.objects.filter(删除的条件).delete()
7.简单完善项目
结合之前的登入案例从数据库中获取值完成登入功能。
7.1登入功能
读取数据库中的值,与提交的数据进行比对。
<form action="" method="post">
from django.shortcuts import render, HttpResponse
def login(request):
if request.method == 'POST':
# 获取post提交的账户密码
username = request.POST.get('username')
password = request.POST.get('password')
from app02 import models
# filter(username=username, password='xxx) 括号内可以携带对个参数,参数于参数之间默认为and的关系
user_obj = models.user.objects.filter(username=username).first()
# 直接以名称去取值,空则用户不存在,有组则说明用户存在。
if user_obj:
# 直接对用户的密码进行比对,数据库密码的值为字符串,输入的密码位数字。
if password == str(user_obj.password):
return HttpResponse('登入成功')
else:
return HttpResponse('密码错误')
else:
return HttpResponse('用户不存在')
return render(request, 'login.html')
objects.filter().first() 获取第一个值
(内部还是使用索引,自己索引操作不安全别人操作,自己使用就好)
原本的操作:
# # select * from User where username='username';
# res = models.User.objects.filter(username=username)
# print(res)
# # < QueryDict: {'username': ['kid'], 'password': ['123']} >
# # < QuerySet[ < User: Userobject >] > 列表套数据对象
# user_obj = res[0] # 索引取值拿到
在user中添加,在打印时触发。
def __str__(self):
return '%s' % self.username
7.2注册功能
开设一个注册功能
获取post提交的数据添加到数据库中。
字段为id(自增的)
username
password
1.第一步添加关系
在urls.py中添加路由与视图的关系。
# 在urls.py中添加
url(r'^register/', views.reg),
2.第二步创建路由
创建简单的路由。
# 在app引用的views下创建reg函数
def reg(request):
return reder(request,'reg.html')
3.第三部创建页面
创建注册页面。
在templates创建reg.html。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js'%}"></script>
</head>
<body>
<h1 class="text-center">注册</h1>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form action="" method="post">
<p>username: <input type="text" name="username" class="form-control"></p>
<p>password: <input type="password" name="password" class="form-control"></p>
<input type="submit" class="btn btn-danger btn-block">
</form>
</div>
</div>
</div>
</body>
</html>

3.第四步获取数据写入
丰富路由功能。
获取post方式提交的帐户名称与密码。
将信息写入数据库中。
from app02 import models # 添加到文件顶部去
def reg(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
models.user.objects.create(username=username, password=password)
return HttpResponse('注册成功')
return render(request, 'reg.html')
res = models.User.objects.create(username=username, password=password)
print(res, res.username, res.password)
# 返回值就是当前被创建对象的本身
8.增加功能
展示所有的用户信息。
点击按钮选择修改。
修改页面中展示用户名和密码,提供参考修改。
修改完成在存入数据库。
8.1展示部分
1.第一步建立关系
# 在urls.py中添加路由与视图的关系。
url(r'^userlist', views.userlist),
2.第二步创建路由
def userlist(request):
return render(request, 'userlist.html')
3.创建页面
在templates创建userlist.html。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户信息</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
<h1 class="text-center"> 数据展示</h1>
<div class="row">
<div class="col-md-8 col-md-offset-2"></div>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>ID</th>
<th>username</th>
<th>password</th>
<th>action</th>
</tr>
</thead>
<tbody>
{% for user_obj in user_querySet %}
<tr>
<td>{{ user_obj.id }}</td>
<td>{{ user_obj.username }}</td>
<td>{{ user_obj.password }}</td>
<td>
<a href="" class="btn btn-primary btn-xs">编辑</a>
<a href="" class="btn btn-danger btn-xs">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
</html>
4.完善路由
def userlist(request):
user_querySet = models.user.objects.all() # .all 获取所有数据
return render(request, 'userlist.html', locals()) # 将xx_querySet 名称空间传递到html

8.2修改数据
1.第一步给按键添加功能
点击标签跳转到数据修改的页面编辑按钮。
点击编辑提交get请求携带需要需要用户的id值。
在templates下的userlist.html。
<a href="/edit_user/?user_id={{ user_obj.id }}" class="btn btn-primary btn-xs">编辑</a>
2.第二步创建路由关系
url(r'^edit_user/', views.edit_user,
3.第三步创建路由
edit_id = request.GET.get('user_id') 获取需要修改的用户id。
def edit_user(request):
user_id = request.GET.get('user_id') # id的值
edit_querySet = models.user.objects.filter(id=user_id).first() # 获取修改用户的id
return render(request, 'edit_user.html', locals()) # 将xx_querySet 名称空间传递到html
4.第四步创建页面
value="{{ edit_querySet.username }} # 展示用户的数据做为修改的参考
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>修改信息</title>
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js'%}"></script>
</head>
<body>
<h1 class="text-center">修改</h1>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form action="" method="post">
<p>username: <input type="text" name="username" class="form-control" value="{{ edit_querySet.username }}"></p>
<p>password: <input type="texe" name="password" class="form-control" value={{ edit_querySet.password }}></p>
<input type="submit" class="btn btn-danger btn-block">
</form>
</div>
</div>
</div>
</body>
</html>>
5.完善路由功能
获取页面修改后post提交的数据。
models.User.objects.filter(id=edit_id).update(username=username,password=password) 更新数据。
def edit_user(request):
user_id = request.GET.get('user_id') # id的值
edit_querySet = models.user.objects.filter(id=user_id).first() # 获取修改用户的id
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
models.user.objects.filter(id=user_id).update(username=username, password=password)
return redirect('/userlist/') # 修改成功跳转到用户信息页面
return render(request, 'edit_user.html', locals()) # 将xx_querySet 名称空间传递到html
# 方式二: 单独更新
edit_obj.username = username
edit_obj.password = password
edit_obj.save()
# 当字段多的时候效率低,从头到尾将数 据字段全更新一遍,无论是字段是否修改。
8.3删除功能
1.第一步给按键添加功能
点击编辑提交get请求携带需要需要用户的id值。
在templates下的userlist.html。
<a href="/delete_user/?user_id={{ user_obj.id }}" class="btn btn-primary btn-xs">删除</a>
2.第二步创建路由关系
url(r'^delete_user/', views.delete_user,
3.第三步创建路由
edit_id = request.GET.get('user_id') # 获取需要修改的用户id。
models.User.objects.filter(id=delete_id).delete() # 使用id直接删除数据。
def delete_user(request):
# 获取用户想要删除的数据id值
delete_id = request.GET.get('user_id')
# 直接去数据库中找到对应的数据删除即可
models.User.objects.filter(id=delete_id).delete()
# 批量删除
return redirect('/userlist/')
1.真正的删除功能应该需要二次确认,
2.删除数据内部其实并不去真正的数据。为数据添加一个标识字段来表示当前数据是否被删除了。
如果数据被删了仅仅只是将字段修改了一个状态
userbane password is_delete
kid 123 0
qz 456 1
查询数据时过滤 is_delete = 0
3236

被折叠的 条评论
为什么被折叠?



