目录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')