Django之ORM简单操作(一)
一. 静态文件配置:
所有的html文件默认都写在templates文件夹下
所有的静态文件(css,js,前端第三方类库)默认都放在static文件夹下
html页面引入外部资源的方式: cdn, 本地(bootstrap)
1. 在项目的settings.py文件中配置环境变量:
( 暴露给外界能够访问服务器静态文件夹下面所有的资源)
2. 在html文件中修改路径 :
3.在前端渲染成功:
补充知识点:
STATIC_URL = '/xxx/' # 接口前缀 跟你的静态文件夹的名字一点关系都没有 # 默认情况下这个前缀跟静态文件夹名字一样!!! # 静态文件配置 STATICFILES_DIRS = [ os.path.join(BASE_DIR,'static'), # 就是你的静态文件夹路径 os.path.join(BASE_DIR,'static1'), os.path.join(BASE_DIR,'static2') ] # ps:会依次查找列表中所有的静态文件路径 找到的话立刻停止,都没有找到返回404
二.登录功能:
小知识点: 路由访问如果不加斜杠 会内部自动重定向加斜杠的路由:
views.py文件:
from django.conf.urls import url from django.contrib import admin from app0 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/', views.login), ]
urls.py文件:
from django.shortcuts import render ,HttpResponse,redirect # Create your views here. def login(request): return render(request,'login.html')
login.html文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <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> <div class="container"> <div class="row"> <h1>登录页面</h1> <div class="col-md-6 col-md-offset-3"> <form action="" method="post"> <p>username:<input type="text" class="form-control" name="username"></p> <p>password:<input type="password" class="form-control" name="password"></p> <input type="submit" class="btn btn-success"> </form> </div> </div> </div> </body> </html>
form表单触发提交数据的动作两种方式:
<input type="submit"> <button></button>
form提交数据的地址如何指定及方式?
action属性控制提交的地址 方式: 1.全路径 <form action="http://127.0.0.1:8000/login/"> 2.只写路径后缀 <form action="/login/"> 3.不写 (默认往当前路径提交)
form表单默认是get请求
根据客户端请求方式的不同执行不同的逻辑代码:
def login(request): # 获取用户端提交的请求方式 print(request.method) # 拿到的请求方式是全大写的字符串 if request.method == 'GET': return render(request,'login.html') elif request.method == 'POST': return HttpResponse("收到了 老弟")
简化:
建议按照下面这种方式书写 减少代码冗余及结构混乱的问题 def login(request): if request.method == 'POST': return HttpResponse('OK') return render(request,'login.html')
#按路径打开一个页面,首先走的是 return render(request,'login.html'),因为走的是GET请求,会弹出一个渲染的form表单页面,
填写数据后,点击submit按钮,会触发POST请求,再走 return HttpResponse('OK')
注意1:请求为POST时要注释一行代码:
注意2: request.POST是一个存放了客户端post提交的所有数据的大字典,如果用get取值取的是列表中的最后一个值,
getlist才是获取字典中的value(列表), getlist应用场景:用户的爱好 多选框
request.GET同上,get请求只需在默认路径后添加 ?username=xxx&password=xxx:
三.基于pymysql完成登录功能
views.py文件:
from django.shortcuts import render ,HttpResponse,redirect import pymysql # Create your views here. def login(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') conn=pymysql.connect( host='127.0.0.1', port=3306, user='root', password='123456', database='day100', charset='utf8', autocommit=True ) cursor=conn.cursor(pymysql.cursors.DictCursor) cursor.execute('select * from userinfo where username=%s and password=%s',(username,password) ) userinfo=cursor.fetchall() if userinfo: return HttpResponse('login success') return render(request, 'login.html')
urls.py文件:
"""day54 URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url from django.contrib import admin from app0 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/', views.login), ]
login.html文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <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> <div class="container"> <div class="row"> <h1>登录页面</h1> <div class="col-md-6 col-md-offset-3"> <form action="" method="post"> <p>username:<input type="text" class="form-control" name="username"></p> <p>password:<input type="password" class="form-control" name="password"></p> <input type="submit" class="btn btn-success"> </form> </div> </div> </div> </body> </html>
数据库文件:
四.pycharm连接数据库
连接数据库:
添加/删除/保存记录:
五. Django连接MySQL
1.需要修改配置文件:
修改前:
修改后:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'day54', 'HOST':'127.0.0.1', 'PORT':3306, 'USER':'root', 'PASSWORD':'123' } } ps:键必须都是大写
2.告诉django用pymysql替换它默认mysqldb模块连接数据库:
方式1:在你的项目文件夹下面的__init__.py 方式2:也可以在你的应用文件夹下面的__init__.py # 固定写法 import pymysql pymysql.install_as_MySQLdb() # 告诉django用pymysql代替mysqldb连接数据库
六.ORM--简易版本注册功能
对象关系映射(ORM):
类 》》》 表
对象 》》》 表记录
对象的属性 》》》 一条记录某个字段对应的值
django的orm不能够自动帮你创建库,但是可以自动帮你创建表:
提示:一个django项目就使用一个库,不要多个django项目使用一个库
models.py文件:
数据库迁移(同步)命令:
python3 manage.py makemigrations 将你的数据库变动记录到一个小本本上(并不会帮你创建表)
python3 manage.py migrate 将你的数据库变动真正同步到数据库中
简便命令窗口:
makemigrations 将你的数据库变动记录到一个小本本上(并不会帮你创建表) migrate 将你的数据库变动真正同步到数据库中
修改模型层里面的跟表相关的所有的数据,只要你修改了就必须重新执行数据库迁移命令
增加字段,需要给它添加默认值:
建表成功:
注册功能:
views.py文件:
from django.shortcuts import render ,HttpResponse,redirect from app0 import models def reg(request): if request.method == 'POST': username=request.POST.get('username') password=request.POST.get('password') # user_obj=models.User.objects.create(name=username,password=password) user_obj=models.User(name=username,password=password) user_obj.save() print(user_obj.pk) print(user_obj.name) print(user_obj.password) return HttpResponse('注册成功') return render(request,'reg.html')
新增数据:
# 操作数据库user表插入数据 # 方式1: user_obj = models.User.objects.create(name=username,password=password) # 方式2: user_obj = models.User(name=username,password=password) user_obj.save() # 对象调用save方法保存到数据库
reg.html文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <h1>注册页面</h1> <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="text" name="password" class="form-control"></p> <input type="submit" class="btn btn-primary"> </form> </div> </div> </div> </body> </html>
七.ORM查询数据库信息
views.py文件:
from django.shortcuts import render ,HttpResponse,redirect from app0 import models def userlist(request): user_list=models.User.objects.all() print(user_list.query) print(user_list) for user_obj in user_list: print(user_obj.name,user_obj.pk) return HttpResponse('ok')
ps:视图函数必须返回一个HttpResponse对象
user_list是一个QuerySet对象:
user_list = models.User.objects.all() # 获取user表所有的数据 # 只要是QuerySet就可以点query查看获取到当前QuerySet对象的内部sql语句 print(user_list.query)
可在models.py文件中修改打印内容:
class User(models.Model): id=models.AutoField(primary_key=True) name=models.CharField(max_length=32) password=models.CharField(max_length=16) def __str__(self): return self.name
前端渲染:
views.py文件:
from django.shortcuts import render ,HttpResponse,redirect from app0 import models def userlist(request): user_list=models.User.objects.all() print(user_list.query) print(user_list) for user_obj in user_list: print(user_obj.name,user_obj.pk) return render(request,'userlist.html',locals())
userlist.html文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <h1>用户信息</h1> <div class="col-md-8 col-md-offset-2"> <table class="table-hover table table-bordered table-striped "> <thead> <tr> <th>id</th> <th>name</th> <th>password</th> </tr> </thead> <tbody> {% for user_obj in user_list %} <tr> <td>{{ user_obj.pk }}</td> <td>{{ user_obj.name }}</td> <td>{{ user_obj.password }}</td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </body> </html>
效果:
八.ORM编辑删除数据
利用a标签href属性 可以指定页面跳转的路径 href可以写全路径 但是推荐写后缀即可:
<a href="/reg/" class="btn btn-success">添加数据</a> # 注意 路径的书写一定要加斜杠
加在userlist.html文件中 (点击添加数据即可跳转到注册页面):
重定向(填写完注册内容要跳转到userlist页面) 可以写别人的网址也可以是自己的路径:
return redirect('/userlist') return redirect('/userlist/')
示例:
删除数据:
在userlist.html文件中增加删除编辑栏:
获取删除对象的id:
在views.py文件中用QuerySet对象的delete()方法进行删除:
def delete_user(request): delete_id=request.GET.get('delete_id') # res=models.User.objects.filter(id=delete_id).first()
#first可将query_set对象中第一个数据对象取出(索引0也同理) models.User.objects.filter(id=delete_id).delete() return redirect('/userlist')
效果(点击删除,该记录消失):
编辑数据:
在userlist.html文件中获取编辑对象的id:
获取数据对象的两种方式:
def edit(request): edit_id=request.GET.get('edit_id') user_obj=models.User.objects.filter(id=edit_id).first() # filter当条件不存在的情况下会返回一个空的queryset对象 user_obj=models.User.objects.get(id=edit_id) # 用get可以直接获取到数据对象本身但是查询条件不存在的情况下直接报错
views.py文件 (用queryset对象的update()方法可更新数据):
def edit(request): if request.method == 'POST': print(request.POST) print(request.GET) username = request.POST.get('username') password = request.POST.get('password') # 获取编辑对象的id方式 edit_id = request.POST.get('edit_id') edit_id = request.GET.get('edit_id') # 更新数据库 models.User.objects.filter(id=edit_id).update(name=username,password=password) return redirect('/userlist') # 获取用户想要修改的数据的id edit_id = request.GET.get('edit_id') # 将该数据查询出来渲染到一个编辑页面 # 查询数据方式1 user_obj = models.User.objects.filter(id=edit_id).first() # 查询数据方式2 # # user_obj = models.User.objects.get(id=edit_id) # print(user_obj,type(user_obj)) # 将当前数据渲染到一个编辑页面上 return render(request,'edit.html',locals())
注意:queryset对象点修改 删除 会作用于对象内部所有的数据对象 类似于批量操作:
方式1: models.User.objects.filter(id=edit_id).update(name=username,password=password) 方式2:获取到当前数据对象 user_obj = models.User.objects.filter(id=edit_id).first() user_obj.name = username user_obj.password=password user_obj.save()
edit.html文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <h1>编辑数据</h1> <div class="col-md-6 col-md-offset-3"> <form action="/edit/?edit_id={{ user_obj.pk }}" method="post"> <input type="hidden" name="edit_id" value="{{ user_obj.pk }}"> <p>username:<input type="text" name="username" value="{{ user_obj.name }}" class="form-control"></p> <p>password:<input type="text" name="password" value="{{ user_obj.password }}" class="form-control"></p> <input type="submit" class="btn btn-warning"> </form> </div> </div> </div> </body> </html>
在edit.html文件中获取编辑对象的id方式:
方式1:利用input隐藏一个标签 <input type="hidden" name="edit_id" value="{{ user_obj.pk }}"> 方式2: <form action="/edit/?edit_id={{ user_obj.pk }}" method="post">
九.图书管理系统表设计
models.py文件中建表模型:
class Book(models.Model): # id字段可以不写 默认会帮你创建一个主键id字段 title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_places=2) # 一对多外键字段的建立 publish = models.ForeignKey(to='Publish') # 默认是与publish表的id字段建立关联 (to=Publish)写法,Publish类必须在上方 # 多对多外键字段建在关联的两张表的任何一张都可以 建议你建在查询频率比较高的那张表里 author = models.ManyToManyField(to='Author') # django orm会自动帮你创建book与author表的第三张表 # 注意多对多字段不会显示到表的字段中 class Publish(models.Model): name = models.CharField(max_length=32) email = models.CharField(max_length=32) class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField()