1.静态文件配置
1. 静态文件:不经常变化的文件,主要针对html文件(CSS文件、js文件、img文件、第三方框架文件)。
2. django针对静态文件资源需要单独开始一个目录统一存放:static目录。该目录下如果各种类型的文件很多,还可以继续创建目录。css目录、js目录、img目录、第三方插件目录:utils目录/plugins目录/libs目录/others目录/或者可以不创(第三方框架较少的情况下)。
3.3 .资源访问:我们在地址栏中之所以可以属于路由获取到相应的资源是因为程序员提前开设了资源的接口。
当我们执行以下代码:
可以看到我们在前端只能拿到标签,不能拿到样式。我们虽然在html文件当中已经拿给设置好了样式,但是由于我们没有配置静态文件资源,所以我们虽然在路由层配置了登陆函数的连接方式,但是我们没有提前开设静态文件资源的访问接口。
2.静态文件相关配置
1. 如果我们想要使用static中静态文件,需要在settings中加入如下语句:
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static' )
]
加入之后template中的html文件中寻找static文件时可以去掉..,此时我们的页面可以使用静态文件。
"""
STATIC_URL = '/static/'是访问静态文件资源的接口前缀(通行证),通行证对了才能继续往下找对应的文件路径。settings中的接口前缀要和html中的link和script标签的前缀保持一致。
os.path.join(BASE_DIR, 'static')是存储静态文件资源的目录名称。接口前缀正确之后,会拿着后面的路径依次去列表中自上而下的查找,找到即停止。
"""
"""
当我们在访问一个网页时如果之前访问过,那么网页可能会混存下来访问过的内容,当我们再次访问时会访问到之前的网页,当我们进行如下设置,网页每一次都是真正地向后端发送请求而不是使用缓存的网页(中文:停用缓存,英文:disable cache)。
"""
2. 当我们需要频繁地改STATIC_URL = '/static/' (静态资源的接口前缀)时,我们需要用以下代码替换掉之前的代码,这样即使接口前缀改动依然可以找到静态文件。
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.css' %}" >
<script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.js' %}" ></script>
1. action:控制数据提交的地址。
1.1 action="" :数据默认发送给当前所在页面的地址。
1.2 action='指定地址' :数据默认发送给指定的地址。
1.3 action="index/" :超当前服务端的index地址提交。
2. method:控制数据提交的方法:默认是get,可以改成post。
get:向服务端索要数据,也可以携带一些额外需求,携带额外数据的方式:IP:PORT?XXX&YYY。XXX和YYY就是携带数据的方式(筛选条件)。但是不能携带敏感数据。
post:向服务端提交数据。也可以携带额外数据,携带额外数据的方试是请求体,请求体携带数据安全性较高,并且没有大小限制。
"""
当我们想要将网页的数据提交给服务端时,我们需要在input标签中指定一个name。可以看到超服务端发送的数据直接体现在了?后面(图1)。
"""
"""
但是此种方法安全性不高,用户名和密码直接暴露在地址栏。此时我们需要在
form标签中添加:method="post"(图1),将提交方式变为post。暂时我们还需要做一步操作:将settings中MIDDLEWARE中'django.middleware.csrf.CsrfViewMiddleware'代码注掉(图2),就可以将页面的数据提交给服务端。pycharm中出现以下字样说明数据已经成功提交给方服务端(图3)。
"""
4.request对象(向客户端发送信息)
1. request.methond:获取请求方式,结果是纯大写的字符串数据,结果是大写的GET/POST的字符串。通过这个关键字我们可以对请求分条件做一些判断,并且返回不同的数据:
views:
def login_func (request ):
if request.method == 'GET' :
return render(request, 'login.html' )
return HttpResponse('数据提交成功' )
urls:
urlpatterns = [
path('admin/' , admin.site.urls),
path('index/' , views.index_func),
path('login/' ,views.login_func)
]
2. request.POST:可以直接拿到用户的提交给服务端的数据,通过下图我们可以看到,我们获取到的内容是一个Querty字典,字典的键是我们在html文件中给input 标签中添加的name。
我们拿到的是一个Querty字典,但是字典的值是一个列表。但是我们也可以通过request.POST.get('键名' )的方法拿到列表中最后一个数据值。
3. 如果我们在html文件中将多个input 标签中的那么改成一样的,那么我们获取到的值是一个列表,我们需要通过request.POST.getlist('键名' )拿到这个列表。
4. 当我们向服务端索要数据是,可以通过request,get的方式拿到?后面的数据,拿到的结果是一个字典。
如果字典对应的值中只有一个元素,那么可以用request.GET.get('键名' )的方式拿到。如果值有多个数据,也可以通过request.GET.getall('键名' )的方式获取。
根据上述内容,我们可以写一个指定用户名和密码的校验功能:
views:
def login_func (request ):
if request.method == 'POST' :
name = request.POST.get('username' )
pwd = request.POST.get('password' )
if name == 'max' and pwd == '123' :
return HttpResponse('登陆成功' )
return HttpResponse('用户名或密码错误' )
return render(request, 'login.html' )
urls:
urlpatterns = [
path('admin/' , admin.site.urls),
path('index/' , views.index_func),
path('login/' ,views.login_func)
]
5.pycharm连接数据库
1. pycharm初次连接数据库需要按照如下操作:
6.django连接数据库
1.j ango自带的sqlite3是一个小型的数据库,功能比较少,主要用于本地测试
我们实际项目中需要替换掉它:
默认配置sqlite3
DATABASES = {
'default' : {
'ENGINE' : 'django.db.backends.sqlite3' ,
'NAME' : os.path.join(BASE_DIR, 'db.sqlite3' ),
}
}
修改为:
DATABASES = {
'default' : {
'ENGINE' : 'django.db.backends.mysql' ,
'NAME' : 'day51' ,
'HOST' : '127.0.0.1' ,
'PORT' : 3306 ,
'USER' : 'root' ,
'PASSWORD' : '123' ,
'CHARSET' : 'utf8'
}
}
2. 当我们改好配置之后依然会报错,此时我们还需要下载一个mysqlclient模块,在终端和pycharm中下载都可以。
django1.X版本需要在项目目录下或者app目录下的__init__.py编写代码
import pymysql
pymysql.install_as_MySQLdb()
django2.X及以上都可以直接通过下载mysqlclient模块解决
pip3.8 install mysqlclient
ps:该模块windows下载问题不大 主要是mac电脑可能有问题
"""
一个Django项目可以连接多个库,但一个库只能连接一个Django项目。所以每创建一个新的Django项目最好新建一个库。
"""
7.ORM简介
ORM:ORM:对象关系映射,能够让不会SQL语句的python程序员,使用python面向对象的语法来操作数据库。
类:表
对象:一条条数据
对象点名字:数据获取字段对应的值
ORM由于高度封装了SQL 所以有时候效率较低 我们需要自己写SQL
8.ORM基本操作
1. 现在models.py编写模型类:
class Girlinfo (models.Model):
id = models.AutoField(primary_key=True )
name = models.CharField(max_length=32 )
age = models.IntegerField()
'''每个字段后面都可以加verbose_name="名字",这个是给字段添加注释'''
2. 数据库迁(将数据记在migrations),需要在pycharm中的命令行执行以下操作:
将操作代码记录下来(migrations目录):python38 manage.py makemigrations
在migrations会产生一个新的py文件,但是我们任然无法看到该表:
我们还需要在pycharm中的终端中进行以下操作,发现我们库中tables目录下多了很多表(这些表在cmd中也可以查的到):
将操作同步到数据库中:python manage.py migrate
'''注意每次在models.py修改了与数据库相关的代码 都需要再次执行上述两步命令'''
9.ORM基本语句
1. ORM基本语句(在views中填写)
from app01 import models
1.1 models.类名.objects.create(字段名=值)
1.2 models.类名.objects.filter (字段名=限制条件),拿到的是一个列表套对象,列表中只有一个元素,我们通过结果[0 ].字段名的方式拿到值。
定义一个同归id 查找员工的方式:
def search (request ):
if request.method == 'POST' :
id = request.POST.get('id' )
empobj = models.emp.objects.filter (id =int (id ))
print (empobj[0 ].id ,empobj[0 ].age,empobj[0 ].gender,empobj[0 ].dep)
print (f"""
员工编号:{empobj[0 ].id }
员工年龄:{empobj[0 ].age}
员工性别:{empobj[0 ].gender}
员工部门:{empobj[0 ].dep}
""" )
return render(request, 'search.html' )
在后台获取到用户输入的编号之后可以的导入下结果:
1.3 models.类名.objects.filter (字段名=限制条件).update(字段名=新的值)
通过id 确定用户,动态回去用户的信息修改:
def change (request ):
if request.method == 'POST' :
id = request.POST.get('id' )
age = request.POST.get('age' )
gender = request.POST.get('gender' )
dep = request.POST.get('dep' )
models.emp.objects.filter (id =id ).update(age=age,gender=gender,dep=dep)
return HttpResponse(f'id为{id } 的员工信息修改完毕' )
return render(request,'change.html' )
1.4 models.类名.objects.filter (字段名=限制条件).delete()
通过指定的id 删除信息:
def delete (request ):
if request.method == 'POST' :
id = request.POST.get('id' )
models.emp.objects.filter (id =id ).delete()
return HttpResponse(f'编号为{id } 的员工删除成功' )
return render(request,'delete.html' )
1.5 models.表名.objects.get(字段名=值):如果能匹配一条数据拿到的是该用户的用户名,取不到值或者取到的数据多于一条会直接报错。经常和try ...except 连用。
10.ORM语句实操
编写一个可视化界面的增删改查功能:
urls:
urlpatterns = [
path('admin/' , admin.site.urls),
path('register/' , views.register),
path('search/' , views.userlistpage),
path('edit_user/' ,views.edit_user),
path('delete_user/' , views.delete_user)
]
models:
class User (models.Model):
name = models.CharField(max_length=32 , verbose_name='用户名' )
age = models.IntegerField(verbose_name='年龄' )
views:
def register (request ):
if request.method == 'POST' :
name = request.POST.get('name' )
age = request.POST.get('age' )
userobj = models.User.objects.filter (name=name)
if userobj:
return HttpResponse(f'用户{name} 已存在,无法重新注册' )
models.User.objects.create(name=name,age=age)
return redirect('/search/' )
return render(request, 'register.html' )
def userlistpage (request ):
userobj = models.User.objects.filter ()
return render(request,'userlistpage.html' ,{'userobj' :userobj})
def edit_user (request ):
target_id = request.GET.get('edit_id' )
target_obj = models.User.objects.filter (id =target_id)[0 ]
if request.method == 'POST' :
new_name = request.POST.get('name' )
new_age = request.POST.get('age' )
if new_name == target_obj.name and new_age == target_obj.age:
return HttpResponse('你未做任何修改,无法提交' )
models.User.objects.filter (id =target_id).update(name=new_name,age=new_age)
return redirect('/search/' )
return render(request,'edit.html' ,{'user_obj' :target_obj})
def delete_user (request ):
target_id = request.GET.get('delete_id' )
models.User.objects.filter (id =target_id).delete()
return redirect('/search/' )
register.html:
<body>
<body>
<div class ="container" >
<div class ="row" >
<h1 class ="text-center" >用户登陆</h1>
<div class ="col-md-6 col-md-offset-3" >
<form action="" method="post" >
<p>姓名:
<input type ="text" class ="form-control" name="name" >
</p>
<p>年龄:
<input type ="text" class ="form-control" name="age" >
</p>
<input type ="submit" class ="btn btn-success btn-block" >
</form>
</div>
</div>
</div>
</body>
edit.html:
<body>
<body>
<div class ="container" >
<div class ="row" >
<h1 class ="text-center" >用户修改</h1>
<div class ="col-md-6 col-md-offset-3" >
<form action="" method="post" >
<p>姓名:
<input type ="text" class ="form-control" name="name" value="{{ user_obj.name }}" >
</p>
<p>年龄:
<input type ="text" class ="form-control" name="age" value="{{ user_obj.age }}" >
</p>
<input type ="submit" class ="btn btn-block btn-block" >
</form>
</div>
</div>
</div>
</body>
userlistpage.html:
<body>
<div class ="container" >
<div class ="row" >
<h1 class ="text-center" >数据展示页</h1>
<div class ="col-md-8 col-md-offset-2" >
<a href="/register/" class ="btn btn-xs btn-success" >添加数据</a>
<table class ="table table-hover table-striped" >
<thead>
<tr>
<td>ID</td>
<td>Name</td>
<td>Age</td>
<td class ="text-center" >Operation</td>
</tr>
</thead>
<tbody>
{% for userdata in userobj %}
<tr>
<td>{{ userdata.pk }}</td>
<td>{{ userdata.name }}</td>
<td>{{ userdata.age }}</td>
<td class ="text-center" >
<a href="/edit_user/?edit_id={{ userdata.pk }}" class ="btn btn-warning btn-xs" >修改</a>
<a href="/delete_user/?delete_id={{ userdata.pk }}" class ="btn btn-danger btn-xs" >删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
"""
1.主键字段可以不写,ORM会自动创建一个id的主键字段。
2.在Django中注释用verbose_name=''来加。
3.pk是primary key 的缩写,可以直接用对象名.pk拿到主键。
4.form表单中能够提交数据的标签:
4.1 <input type="submit">
4.2<button></button>
"""
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!