Django初始项目
创建app
在命令行输入
D:\untitled\mysite>python manage.py startapp app01
创建后目录
新建app后再setting中进行设置
# 告诉Django有那些app INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # 两种写法 # 'app01.apps.App01Config', 'app01' ]
创建Django项目时创建app,setting会自动添加。
目录结构以及自动添加
views.py专门用来放函数
用来定义处理请求的函数
from django.shortcuts import render,redirect,HttpResponse
HttpResponse("要返回的内容") --> 用于直接返回内容
render(request,"html文件",{"k":v}) --> 返回一个html文件或打开文件进行字符串替换
redirect("URL") --> 告诉用户浏览器去访问其他的浏览器
request相关:
request.POST --> 获取POST请求的数据
request.method --> 查看请求的方法
from django.shortcuts import render,redirect # Create your views here. def login(request): error_msg = '' if request.method == "POST": email = request.POST.get("email", None) pwd = request.POST.get("pwd", None) print(email, pwd) if email == 'wzh@qq.com' and pwd == '123': # 登陆成功跳转 redirect return redirect("http://www.baidu.com") else: # 登陆失败 字符串替换 error_msg = "邮箱或密码错误!" return render(request,"login.html",{"error":error_msg})
新建Django配置检查
1.Templates(存放HTML文件的配置)--> 找HTML文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
1.1创建一个登陆页面
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/fontawesome/css/font-awesome.min.css"> <title>login</title> <style> body { background-color: #eee; } </style> </head> <body> <div class="container"> <div class="row"> <div class="col-md-4 col-md-offset-4" style="margin-top: 100px"> <h1 class="text-center">请登录</h1> <form class="form-horizontal" action="/login/" method="POST"> <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label"></label> <div class="input-group col-sm-8"> <span class="input-group-addon"><i class="fa fa-envelope-o fa-fw"></i></span> <input type="email" name="email" class="form-control" id="inputEmail3" placeholder="Email"> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label"></label> <div class="input-group col-sm-8"> <span class="input-group-addon"><i class="fa fa-key fa-fw"></i></span> <input type="password" name="pwd" class="form-control" id="inputPassword3" placeholder="Password"> </div> </div> <div class="form-group"> <div class="input-group col-sm-offset-2 col-sm-8"> <div class="checkbox"> <label> <input type="checkbox"> 记住我 </label> </div> </div> </div> <div class="form-group"> <div class="input-group col-sm-offset-2 col-sm-8"> <button type="submit" class="btn btn-primary btn-block">登录</button> </div> </div> <p class="text-danger text-center">{{ error }}</p> </form> </div> </div> </div> </body> </html>
2.静态文件(css/js/图片)静态文件夹别名及静态文件夹位置
# 静态文件夹别名 STATIC_URL = '/static/' # 静态文件夹的位置 STATICFILES_DIRS = [ os.path.join(BASE_DIR,"static"), ]
2.1创建静态文件夹并导入文件
3.注释setting中带有csrf内容
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
启动项目配置关系
Django WEB请求流程:
1.启动Django项目,等待用户连接
2.浏览器在地址栏输入url,连接我的Django项目
3.在urls.py中找路径和函数的对应关系
4.执行对应的函数
5.返回响应
urls中设置,设置完成后进行登陆。
from django.contrib import admin from django.urls import path from django.conf.urls import url from app01 import views # 保存了路径和函数对应的关系 urlpatterns = [ path('admin/', admin.site.urls), url(r'^login/', views.login), ]
效果页面
ORM
对象关系映射(英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping)。
类 --> 数据表 --> 创建表/删除表/修改表
对象 --> 数据行 --> 数据的增删该查
属性 --> 字段
使用Django的ORM步骤
1.创建数据库(并指定默认字符集)。
mysql> create database if not exists django_db default charset utf8; Query OK, 1 row affected (0.01 sec)
2.在Django项目中配置链接数据库的配置。
# 数据库相关的配置 DATABASES = { 'default': { # 连接的数据库类型 'ENGINE': 'django.db.backends.mysql', # 连接数据库的地址 'HOST':'127.0.0.1', # 端口 'POST':3306, # 数据库名称 'NAME':'django_db', # 用户密码 密码为空可以不写 'USER':'root', } }
3.Django连接数据库 mysqldb(不支持python3) 、pymysql 。在__Init__.py中设置
import pymysql pymysql.install_as_MySQLdb()
4.在app下面的models.py文件中定义一个类,这个类必须继承models.Mode
from django.db import models # Create your models here. # ORM相关的只能写在这个文件里 class UserInfo(models.Model): # 创建一个自增主键 id = models.AutoField(primary_key=True) # 创建一个不能为空char类型
name = models.CharField(null=False,max_length=20)
5.在当前目录终端执行如下命令
5.1 python manage.py makemigrations
5.2 python manage.py migrate
5.3 在数据库中查看执行结果
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
mysql> show tables; +----------------------------+ | Tables_in_django_db | +----------------------------+ | app01_userinfo | | auth_group | | auth_group_permissions | | auth_permission | | auth_user | | auth_user_groups | | auth_user_user_permissions | | django_admin_log | | django_content_type | | django_migrations | | django_session | +----------------------------+ 11 rows in set (0.00 sec) mysql> desc app01_userinfo; +-------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(20) | NO | | NULL | | +-------+-------------+------+-----+---------+----------------+ 2 rows in set (0.04 sec) mysql>
6.数据库表操作
6.1 删除数据库中表,注释创建表的类,运行之前两条命令。
6.2 修改表,在创建类中修改,重新执行命令。
pycharm连接数据库
1.在pycharm中选择
2.右边会出现database,选择相应选项,出现下面选框填写测试。
3.点击选项后弹出框可以写sql语句。
4.向表里面添加数据。点击需要修改的表,点+添加数据,完成后点击db提交到数据库。
用户操作
展示用户
1.在路径与函数对应关系中添加一个用户展示
# 保存了路径和函数对应的关系 urlpatterns = [ path('admin/', admin.site.urls), url(r'^login/', views.login), url(r'^user_list/', views.user_list), ]
2.跳转到views.py中添加函数并进行测试
# 查询数据库中的数据需要导入类的模块 from app01 import models # 展示所有的用户的函数 def user_list(request): # 去数据库中查询所有的用户 通过ORM工具 ret = models.UserInfo.objects.all() print(ret) print(ret[0]) print(ret[0].id,ret[1].name) return HttpResponse("ok")
2.1拿到数据返回页面
def user_list(request): # 去数据库中查询所有的用户 通过ORM工具 ret = models.UserInfo.objects.all() return render(request,"user_list.html",{"user_list":ret})
2.2在temlates中创建对应的user_list的html文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户列表</title> </head> <body> <table border="1"> <thead> <tr> <th>id值</th> <th>用户名</th> </tr> </thead> <tbody> {# 循环拿到相应的数据#} {% for user in user_list %} <tr> <td>{{ user.id }}</td> <td>{{ user.name }}</td> </tr> {% endfor %} </tbody> </table> </body> </html>
2.3访问user_list页面
2.4 对用户表中添加删除数据查看效果。
添加用户
1.在urls中添加对用关系。
url(r'^add_user/', views.add_user),
2.在user_list文件中添加一个跳转标签
<a href="/add_user/">添加用户</a>
3.在views添加函数add_user
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 添加用户的函数 def add_user(request): # 第一次请求返回一个页面 if request.method == 'POST': # 用户填写了数据并发送post请求 new_name = request.POST.get("username") # 去数据库中创建一条记录 models.UserInfo.objects.create(name=new_name) return HttpResponse("ok") return render(request,"add_user.html")
3.1添加成功直接返回用户列表
# 添加用户的函数 def add_user(request): # 第一次请求返回一个页面 if request.method == 'POST': # 用户填写了数据并发送post请求 new_name = request.POST.get("username") # 去数据库中创建一条记录 models.UserInfo.objects.create(name=new_name) return redirect("/user_list/") return render(request,"add_user.html")
4.在temlates中创建add_user的html页面。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>添加用户</title> </head> <body> <form action="/add_user/" method="POST"> <p>用户名 <input type="text" name="username"> </p> <p> <input type="submit" value="提交"> </p> </form> </body> </html>
补充__str__知识
1.如下打印出来的是内存地址。
class Person(): def __init__(self,name,age): self.name = name self.age = age p1 = Person("xiaohei",18) print(p1) # <__main__.Person object at 0x0000025BFCC2A208>
2.添加一个__str__后print调用的就是__str__
class Person(): def __init__(self,name,age): self.name = name self.age = age def __str__(self): return "<{}-{}>".format(self.name,self.age) p1 = Person("xiaohei",18) print(p1) # <xiaohei-18>
图书管理系统
环境搭建
1.数据库中创建库
mysql> create database if not exists book_db default charset utf8; Query OK, 1 row affected (0.06 sec)
2.创建项目
3.文件配置检查
3.1添加应用(在setting中)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app_book.apps.AppBookConfig', ]
3.2注释
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
3.3检查html文件路径
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
3.4配置数据库
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'HOST':'127.0.0.1', 'PORT':3306, 'USER':'root', 'NAME':'book_db', 'PASSWORD':'', } }
在项目的__init__.py中设置pymysql替换MySQLdb
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import pymysql pymysql.install_as_MySQLdb()
3.5静态文件路径配置
在当前目录下创建静态文件夹static,复制相应的文件到路径下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 静态文件夹别名 STATIC_URL = '/static/' # 静态文件夹的位置 STATICFILES_DIRS = [ os.path.join(BASE_DIR,"static"), ]
创建数据表
1.在项目的models.py文件中创建类。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 出版社 class Publisher(models.Model): id = models.AutoField(primary_key=True) # 自增主键 name = models.CharField(max_length=50,null=False,unique=True)
启动项目执行命令
- python manage.py makemigrations
- python manage.py migrate
2.在数据库中查看表是否创建。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
mysql> show tables; +----------------------------+ | Tables_in_book_db | +----------------------------+ | app_book_publisher | | auth_group | | auth_group_permissions | | auth_permission | | auth_user | | auth_user_groups | | auth_user_user_permissions | | django_admin_log | | django_content_type | | django_migrations | | django_session | +----------------------------+ 11 rows in set (0.00 sec) mysql>
3.在表中添加测试数据。
展示
1.导入模块建立对应关系
from django.conf.urls import url from app_book import views urlpatterns = [ path('admin/', admin.site.urls), url(r'^publister_list/', views.publister_list), ]
2.在views中添加函数
def publister_list(request): # 去数据库取数据,填充到html,给用户返回 ret = models.Publisher.objects.all() return render(request,"publister_list.html",{"publister_list":ret})
3.在templates中创建对应的html文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>出版社列表</title> </head> <body> <table border="1"> <thead> <tr> <th>序号</th> <th>ID</th> <th>出版社名称</th> </tr> </thead> <tbody> {% for foo in publister_list %} <tr> <td>{{ forloop.counter }}</td> <td>{{ foo.id }}</td> <td>{{ foo.name }}</td> </tr> {% endfor %} </tbody> </table> </body> </html>
4.启动项目在浏览器输入url地址。
添加
1.在urls中添加对应关系。
url(r'^add_publister/', views.add_publister),
2.在views中添加函数
# 添加出版社 def add_publister(request): # 用户第一次请求,返回填写的html页面 if request.method == 'POST': # 得到请求的数据 new_name = request.POST.get("publister_name") # 将数据更新到数据库中 models.Publisher.objects.create(name=new_name) # 返回页面 展示更新后的数据 return redirect("/publister_list/") return render(request,"add_publister.html")
3.在templates中新建添加页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>添加出版社</title> </head> <body> <h1>添加出版社</h1> <form action="/add_publister/" method="POST"> <input type="text" name="publister_name"> <input type="submit" value="提交"> </form> </body> </html>
4.重新启动,在浏览器操作
删除
1.在出版社列表页面添加一个删除操作。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>出版社列表</title> </head> <body> <a href="/add_publister/">添加出版社</a> <table border="1"> <thead> <tr> <th>序号</th> <th>ID</th> <th>出版社名称</th> <th>操作</th> </tr> </thead> <tbody> {% for foo in publister_list %} <tr> <td>{{ forloop.counter }}</td> <td>{{ foo.id }}</td> <td>{{ foo.name }}</td> <td><button>删除</button></td> </tr> {% endfor %} </tbody> </table> </body> </html>
2.用一个a标签来做删除链接,在urls中添加对应关系,在views中增加删除函数。
2.1出版社页面调整,增加a标签,跳转到删除函数,传入唯一对应的id值。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>出版社列表</title> </head> <body> <a href="/add_publister/">添加出版社</a> <table border="1"> <thead> <tr> <th>序号</th> <th>ID</th> <th>出版社名称</th> <th>操作</th> </tr> </thead> <tbody> {% for foo in publister_list %} <tr> <td>{{ forloop.counter }}</td> <td>{{ foo.id }}</td> <td>{{ foo.name }}</td> {# 需要拼接一个id#} <td><a href="/delete_publister/?id={{ foo.id }}">删除</a></td> </tr> {% endfor %} </tbody> </table> </body> </html>
2.2添加删除函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 删除函数
def delete_publister(request):
# 删除指定的数据
# 1.从get请求的参数里面拿到将要删除数据的ID
del_id = request.GET.get("id",None)
# 2.取到id值去数据库删除当前id值的数据
if del_id:
# 根据id值查询到数据
del_obj = models.Publisher.objects.get(id=del_id)
# 删除
del_obj.delete()
# 返回删除后的页面,跳转到出版社的列表页,查看删除是否成功
return redirect("/publister_list/")
else:
return HttpResponse("数据不存在!")
编辑
1.在出版社页面中添加编辑跳转按钮并指定选中id。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>出版社列表</title> </head> <body> <a href="/add_publister/">添加出版社</a> <table border="1"> <thead> <tr> <th>序号</th> <th>ID</th> <th>出版社名称</th> <th>操作</th> </tr> </thead> <tbody> {% for foo in publister_list %} <tr> <td>{{ forloop.counter }}</td> <td>{{ foo.id }}</td> <td>{{ foo.name }}</td> {# 需要拼接一个id#} <td> <a href="/delete_publister/?id={{ foo.id }}">删除</a> <a href="/edit_publister/?id={{ foo.id }}">编辑</a> </td> </tr> {% endfor %} </tbody> </table> </body> </html>
2.在urls中添加对应关系
url(r'^edit_publister/', views.edit_publister),
3.在templates中创建html页面,得到id,选中时默认的出版社名字。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>编辑出版社</title> </head> <body> <h1>编辑出版社</h1> <form action="/edit_publister/" method="POST"> {# 得到选中的id,且不展示#} <input type="text" name="id" value="{{ publister.id }}" style="display: none"> {# 在函数对应关系中传入的默认选中出版社#} <input type="text" name="publister_name" value="{{ publister.name }}"> <input type="submit" value="提交"> <p style="color: red">{{ error }}</p> </form> </body> </html>
4.在views中创建编辑函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 编辑出版社 def edit_publister(request): # 用户修改完出版社名字,点击提交,发出新的名字 if request.method == "POST": edit_id = request.POST.get("id") new_name = request.POST.get("publister_name") # 更新出版社 根据id更新出版社名字 # 根据得到的id找到对应的数据 edit_publister = models.Publister.objects.get(id=edit_id) # 上面得到的对象进行更名 edit_publister.name = new_name # 保存 edit_publister.save() return redirect("/publister_list/") # get请求取到url中id参数 edit_id = request.GET.get("id") if edit_id: # 获取到当前编辑的出版社对象 publister_obj = models.Publister.objects.get(id=edit_id) return render(request,"edit_publister.html",{"publister":publister_obj}) else: return HttpResponse("编辑的出版社不存在!")
添加书籍
1.在models中创建表,该表和出版社表id外键关系。
class Book(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(max_length=100,null=False,unique=True) # 和出版社关联的外键字段 publisher_id = models.ForeignKey(to=Publister,on_delete=models.CASCADE)
2.执行命令创建表
2.1在pycharm中可以选择快捷方式
- makemigrations
- migrate
3.创建对应关系,函数,html文件。
3.1对应关系
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 书对应关系 url(r'^book_list/', views.book_list),
3.2函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 展示书的列表 def book_list(request): # 找到所有的书 all_book = models.Book.objects.all() # 在html页面渲染数据 return render(request,"book_list.html",{"all_book":all_book})
3.3html文件,直接循环外键取到的时对象,直接取到对应的属性。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>书籍列表</title> </head> <body> <h1>所有的书籍</h1> <table border="1"> <thead> <tr> <th>序号</th> <th>ID</th> <th>书名</th> <th>publisher</th> </tr> </thead> <tbody> {% for foo in all_book %} <tr> <td>{{ forloop.counter }}</td> <td>{{ foo.id }}</td> <td>{{ foo.title }}</td> <td>{{ foo.publisher.name }}</td> </tr> {% endfor %} </tbody> </table> </body> </html>