目錄css
用pycharm >settings建立項目時能夠自定義一個app名,幫你自動建立一個應用,並自動建立template文件夾,查看配置INSTALLED_APPS沒有自動添加新建的app,若是沒有手動添加,TEMPLATES列表的「DIRS」若是沒有添加templates文件夾的路徑,手動添加一下。html
登陸功能
1.路由l(r'^login/', views.login),訪問若是不加斜槓,內部自動重定向加斜槓的路由前端
全部的python
2.全部前端渲染出來的瀏覽器頁面,都是在後端寫好的html文件,這些文件默認都寫在templates文件夾;
3.全部的靜態文件(css,js,前端第三方類庫)默認都放在static文件夾下mysql
html頁面引入外部資源的方式
1) cdn
2) 本地jquery
靜態文件配置,暴露給外界可以訪問服務器靜態文件夾下面全部的資源web
STATIC_URL = '/static/' # 訪問靜態文件資源接口前綴
"""
若是你想訪問靜態文件資源 你必有以上面的名字開頭
你纔有訪問靜態文件資源的權限sql
一旦你是以接口前綴開頭 我會拿着接口前綴後面的文件路徑
去下面的列表中從上往下去每個文件夾 找尋是否存在該文件 若是是直接返回
"""
本身手動配置路徑
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static'), # 就是你的靜態文件夾路徑
os.path.join(BASE_DIR,'static1'),
os.path.join(BASE_DIR,'static2')]數據庫
STATIC_URL = '/static/' # 接口前綴(template文件夾中的每個html文件內的導入連接前綴) 跟你的靜態文件夾的名字一點關係都沒有,默認狀況下這個前綴跟靜態文件夾名字同樣!
template 的html文件中導入的JQuery,css,js連接前綴會到static文件夾查找對應的導入文件,django
ps:html文件內的導入連接前綴會依次查找列表中全部的靜態文件路徑是否與本身的連接匹配(是否有前綴static的路徑文件)找到的話馬上中止,都沒有找到返回404
html頁面上的接口前綴跟你的配置文件中接口前綴動態綁定 在html頁面上 固定寫句式 {% load static %} <script src='{% static 'Bootstrap/css/min.css' %}'></script>
form表單觸發提交數據的動做兩種方式
<input type="submit"> <button></button>
orm提交數據的地址指定方式
action屬性控制提交的地址
1.全路徑
<form action="http://127.0.0.1:8000/login/",method="post"> # method不寫默認是get請求
改爲post請求,記得將settings配置文件中的中間件註銷掉。否則報黃頁
2.只寫路徑後綴
<form action="/login/">
3.不寫 (默認往當前路徑提交)
form表單默認是get請求
<!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/css/bootstrap.min.css"> <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script> </head> <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>username:<input type="text" class="form-control" name="username"></p> <p>username:<input type="text" class="form-control" name="username"></p> <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>
根據客戶端請求方式的不一樣執行不一樣的邏輯代碼 from django.shortcuts import render,HttpResponse # Create your views here. def login(request): # print(request) # request:<WSGIRequest: GET '/login/'> # print(request.method) # 獲取的是用戶的請求方式,是全大寫的字符串 if request.method == "POST": print(request.POST) # 你就把它當成一個大字典裏面存放了客戶端post提交的全部的數據 # <QueryDict: {'username': ['zhang'], 'password': ['123']}> print(request.POST.get('username')) # value雖然是個列表可是獲取value的時候拿到倒是單個元素 # 默認只會取value列表裏面的最後一個元素 # <QueryDict: {'username': ['zhang', 'li', 'zhao'], 'password': ['1234']}> # 一次性獲取value列表裏面全部的數據須要用getlist() print(request.POST.getlist('username')) # ['zhang', 'li', 'zhao'] print(request.POST['password']) # 不推薦使用該方法獲取數據 return HttpResponse('登陸成功!') return render(request,'login.html') ''' 獲取value列表裏面全部的元素須要使用getlist 應用場景:用戶的愛好 多選框get只會獲取到value列表的最後一個元素 '''
# print(request.environ) ''' {'ALLUSERSPROFILE': 'C:\\ProgramData', 'APPDATA': 'C:\\Users\\Administrator\\AppData\\Roaming', 'COMMONPROGRAMFILES': 'C:\\Program Files\\Common Files', 'COMMONPROGRAMFILES(X86)': 'C:\\Program Files (x86)\\Common Files', 'COMMONPROGRAMW6432': 'C:\\Program Files\\Common Files', 'COMPUTERNAME': 'WIN-KIJ962UBO3B', 'COMSPEC': 'C:\\windows\\system32\\cmd.exe', 'DJANGO_SETTINGS_MODULE': 'day52.settings', 'FP_NO_HOST_CHECK': 'NO', 'HOMEDRIVE': 'C:', 'HOMEPATH': '\\Users\\Administrator', 'LOCALAPPDATA': 'C:\\Users\\Administrator\\AppData\\Local', 'LOGONSERVER': '\\\\WIN-KIJ962UBO3B', 'NUMBER_OF_PROCESSORS': '4', 'OS': 'Windows_NT', 'PATH': 'G:\\python36;G:\\python36\\Scripts;G:\\Python27;G:\\Python27\\Scripts;G:\\Python27\\Scripts;G:\\python36\\Scripts;C:\\windows\\system32;C:\\windows;C:\\windows\\System32\\Wbem;C:\\windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Users\\Administrator\\Desktop\\new 1.py;G:\\sub3;G:\\MYSQL\\bin;G:\\Git\\cmd;G:\\Git\\mingw64\\bin;G:\\Git\\usr\\bin;G:\\python36\\lib\\site-packages\\numpy\\.libs;G:\\python36\\lib\\site-packages\\numpy\\.libs', 'PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC', 'PROCESSOR_ARCHITECTURE': 'AMD64', 'PROCESSOR_IDENTIFIER': 'Intel64 Family 6 Model 69 Stepping 1, GenuineIntel', 'PROCESSOR_LEVEL': '6', 'PROCESSOR_REVISION': '4501', 'PROGRAMDATA': 'C:\\ProgramData', 'PROGRAMFILES': 'C:\\Program Files', 'PROGRAMFILES(X86)': 'C:\\Program Files (x86)', 'PROGRAMW6432': 'C:\\Program Files', 'PSMODULEPATH': 'C:\\windows\\system32\\WindowsPowerShell\\v1.0\\Modules\\', 'PUBLIC': 'C:\\Users\\Public', 'PYCHARM_HOSTED': '1', 'PYCHARM_MATPLOTLIB_PORT': '49203', 'PYTHONIOENCODING': 'UTF-8', 'PYTHONPATH': 'G:\\PyCharm 2018.1.4\\helpers\\pycharm_matplotlib_backend;G:\\Python代碼平常\\day52' 'PYTHONUNBUFFERED': '1', 'SESSIONNAME': 'Console', 'SYSTEMDRIVE': 'C:', 'SYSTEMROOT': 'C:\\windows', 'TEMP': 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp', 'TMP': 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp', 'USERDOMAIN': 'WIN-KIJ962UBO3B', 'USERNAME': 'Administrator', 'USERPROFILE': 'C:\\Users\\Administrator', 'WINDIR': 'C:\\windows', 'WINDOWS_TRACING_FLAGS': '3', 'WINDOWS_TRACING_LOGFILE': 'C:\\BVTBin\\Tests\\installpackage\\csilogfile.log', 'RUN_MAIN': 'true', 'SERVER_NAME': 'WIN-KIJ962UBO3B', 'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_PORT': '8000', 'REMOTE_HOST': '', 'CONTENT_LENGTH': '', 'SCRIPT_NAME': '', 'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_SOFTWARE': 'WSGIServer/0.2', 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/login/', 'QUERY_STRING': '', 'REMOTE_ADDR': '127.0.0.1', 'CONTENT_TYPE': 'text/plain', 'HTTP_HOST': '127.0.0.1:8000', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate, br', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9,en;q=0.8', 'HTTP_COOKIE': 'csrftoken=YN8zgrVrZ4rrIZpWwFmyKY6yp2ggTCaUsDT4HJYUn36OY7Ijk7LpGTHtKbNML8EB', 'wsgi.input': <_io.BufferedReader name=656>, 'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>, 'wsgi.version': (1, 0), 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.multithread': True, 'wsgi.multiprocess': False, 'wsgi.file_wrapper': <class 'wsgiref.util.FileWrapper'>} '''
直接上圖:
能夠達到與數據庫的數據同時更新 刪除;
其實python解釋器在運行django程序時,django的orm底層操做數據庫的python模塊默認是mysqldb而非pymysql,然而對於解釋器而言,python2.x解釋器支持的操做數據庫的模塊是mysqldb,而python3.x解釋器支持的操做數據庫的模塊則是pymysql,,毫無疑問,目前咱們的django程序都是運行於python3.x解釋器下,因而咱們須要修改django的orm默認操做數據庫的模塊爲pymysql,具體作法以下:
settings.py文件>DATABASES
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }} django鏈接數據庫 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鏈接數據庫
對象關係映射 類 》》》 表 對象 》》》 表記錄 對象的屬性 》》》 一條記錄某個字段對應的值
django的orm不可以自動幫你建立庫,可是能夠自動幫你建立表
提示:一個django項目就使用一個庫,不要多個django項目使用一個庫
from django.db import models # Create your models here. class User(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) password = models.CharField(max_length=16)
cmd 終端敲下面命令,將建表的各字段記在migration文件夾下面的一個自動生成的.py文件中,而後將建的表的字段同步更新到數據庫當中。
# 數據庫遷移(同步)命令(******) python3 manage.py makemigrations # 將你的數據庫變更記錄到一個小本本上(並不會幫你建立表) python3 manage.py migrate # 將你的數據庫變更正在同步到數據庫中
改字段(字段的長度)
# 直接修改代碼 而後執行數據庫遷移命令便可(兩條一條不能少) # 方式1 設置默認值 email = models.EmailField(default='123@qq.com') # varchar # 方式2 容許字段爲空 phone = models.BigIntegerField(null=True) # 直接在提示中給默認值 gender = models.CharField(max_length=32)
增字段
直接增長對應的字段 而後再執行數據庫遷移命令便可(謹慎使用)
字段的刪除
直接註釋掉對應的字段 而後再執行數據庫遷移命令便可(謹慎使用)
# 查 data = models.User.objects.filter(username=username) #queryset對象 <QuerySet [<User: User object>]>,filter當條件不存在的狀況下會返回一個空的queryset對象==><QuerySet []> <class'django.db.models.query.QuerySet'> # 方式1: data = models.User.objects.filter(username=username)[0] # 不推薦使用 # 方式2 data = models.User.objects.filter(username=username).first() # 獲取列表(QuerySet對象)內索引0的數據對象數據對象,數據對象經過點方法獲取屬性值,queryset對象支持索引取值 可是不推薦你使用 推薦使用自帶的.first()幫你獲取第一條數據 """ filter返回的結果是一個"列表",裏面纔是真正數據對象 filer括號內能夠放多個關鍵字參數 這多個關鍵字參數在查詢的時候 是and關係 """ user_list = models.User.objects.all() #查出全部的數據對象,返回的是列表,裏面是一個個User對象 <QuerySet [<User: User object>, <User: User object>]> """ 結果是一個"列表" 裏面是一個個的數據對象 """
登陸功能代碼
def login(request): if request.method=='POST': username = request.POST.get('username') password = request.POST.get('password') data = models.User.objects.filter(name = username) if not data: return HttpResponse('當前用戶不存在!') user_obj = data[0] print("對象的id:",user_obj.pk) # 同 user_obj.id 獲取主鍵的id值 # data1 = models.User.objects.all() if user_obj.password == password: return HttpResponse('登陸成功!') return HttpResponse('密碼錯誤') return render(request,'login.html')
# 方式1: user_obj = models.User.objects.create(username=username,password=password) print(user_obj,user_obj.username,user_obj.password) # create方法會有一個返回值 返回值就是當前被建立的對象自己 # 方式2: user_obj = models.User(name=username,password=password) user_obj.save() # 對象調用save方法保存到數據庫
添加用戶代碼
# userlist.py文件 以表格的形式向瀏覽器頁面展現用戶信息,點擊新增按鈕,跳到添加用戶頁面 <!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> {% load static %} {# 改爲這種形式,即便urls文件中的STATIC_URL = '/static/'後綴名改爲其餘的,link和script中的static前綴也能識別#} <link rel="stylesheet" href="{% static 'bootstrap-3.3.7/css/bootstrap.min.css' %}"> <script src="{% static 'bootstrap-3.3.7/js/bootstrap.min.js' %}"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h1 class="text-center">數據展現</h1> <a href="/add_user/" class="btn btn-success">新增</a> <table class="table table-hover table-bordered table-striped"> <thead> <tr> <th>id</th> <th>username</th> <th>password</th> <th>actions</th> </tr> </thead> <tbody> {% for user in user_list %} <tr> <td>{{user.id}}</td> <td>{{user.name}}</td> <td>{{user.password}}</td> <td> <!--href跟的是跳轉的後綴,問號後是get請求攜帶的參數 --> <a href="/edit_user/?edit_id={{ user.id }}" class="btn btn-primary btn-sm">編輯</a> <a href="/delete_user/?delete_id={{ user.id }}" class="btn btn-danger btn-sm">刪除</a> </td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </body> </html>
# add_user.py文件 輸入信息,點擊提交,跳到查看用戶頁面,此時新增用以添加 <!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> {% load static %} <link rel="stylesheet" href="{% static 'bootstrap-3.3.7/css/bootstrap.min.css' %}"> <script src="{% static 'bootstrap-3.3.7/js/bootstrap.min.js' %}"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h1 class="text-center">添加用戶</h1> <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-warning pull-right"> </form> </div> </div> </div> </body> </html>
def userlist(request): user_list = models.User.objects.all() # print(user_list) # <QuerySet [<User: User object>, <User: User object>]> return render(request,'userlist.html',{'user_list':user_list}) def add_user(request): if request.method=='POST': username = request.POST.get('username') password = request.POST.get('password') user_list = models.User.objects.filter(name = username) if user_list: return HttpResponse('用戶已存在!') # 增 user_obj = models.User.objects.create(name=username,password=password) print(user_obj,user_obj.name,user_obj.password) # 跳轉到查看頁面 return redirect('/userlist/') return render(request,'add_user.html')
# 方式1: models.User.objects.filter(id=edit_id).update(username=username,password=password) # 方式2:獲取到當前數據對象 user_obj = models.User.objects.filter(id=edit_id).first() user_obj.name = username user_obj.save() """ 批量操做 會將filter查詢出來的列表中全部的對象所有更新 """
修改用戶代碼
輸入後綴/userlist/,返回給用戶全部用戶的信息,用戶點擊「編輯」「按鈕,觸發edit_user函數,攜帶id,後端獲取id,去數據區查取對應的用戶對象,經過對象點屬性,將用戶的屬性值("edit_user.html"文件)渲染到瀏覽器,用戶點擊提交按鈕,後端再將用戶提交(post請求)的已修改的數據保存到數據庫,並將修改事後的全部用戶的信息(userlist.html文件)渲染到前端
def edit_user(request): # print(request.GET) # <QueryDict: {'edit_id': ['2']}> if request.method =='POST': username = request.POST.get('username') password = request.POST.get('password') models.User.objects.filter(id=edit_id).update(name=username,password=password) return redirect('/userlist/') # 如何獲取用戶想要編輯的數據ID 利用get請求攜帶參數的方式 獲取用戶想要編輯的數據id值 edit_id = request.GET.get('edit_id') # 將用戶想要編輯的數據查詢出來 展現到編輯頁面上 供用戶修改 # edit_obj = models.User.objects.filter(id=edit_id)[0] edit_obj = models.User.objects.filter(id=edit_id).first() # 返回一個編輯頁面 該編輯頁面上 應該展現用戶想要編輯的數據信息 return render(request,'edit_user.html',{'edit_obj':edit_obj})
<!--edit_user.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> {% load static %} <link rel="stylesheet" href="{% static 'bootstrap-3.3.7/css/bootstrap.min.css' %}"> <script src="{% static 'bootstrap-3.3.7/css/bootstrap.min.css' %}"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h1 class="text-center">編輯用戶</h1> <form action="" method="post"> <p>username:<input type="text" class="form-control" name="username" value="{{ edit_obj.name }}"></p> <p>password:<input type="text" class="form-control" name="password" value="{{ edit_obj.password }}"></p> <input type="submit" class="btn btn-info pull-right"> </form> </div> </div> </div> </body> </html>
models.User.objects.filter(id=delete_id).delete() """ 批量操做 會將filter查詢出來的列表中全部的對象所有刪除 """
def delete_user(request): delete_id = request.GET.get('delete_id') models.User.objects.filter(id = delete_id).delete() return render(request,'userlist.html')