Django是一个Web框架,咱们使用它就是由于它可以把先后端解耦合并且可以与数据库创建ORM,这样,一个Python开发工程师只须要干本身开发的事情就能够了,而在使用以前就咱们须要给Django作文件配置和数据库配置html
上一章写过的文章,有些朋友反应,对于Web框架部分写的过于深刻,而对于Django项目讲解的比较少,感受实用性不强,我想说前端
# 万物本源,你在写项目的时候,若是连最基本的原理都不懂,出了Bug你怎么解决 # 若是是在看不懂,只须要理解http通讯原理就能够了,之后我会翻译Django网站部份内容并带你们解读Djaogo源码,若是那时候你还在看个人博客的话,你会发现如今这些都是A piece Of cake
今天我会带你们真正写一个Django项目,对于入门来讲是有点难度的,由于逻辑比较复杂,可是真正的知识就是函数与面向对象,这也是培养用Django思惟写项目的开始python
Django模版文件配置mysql
文件路径 test_site -- test_site -- settings.pygit
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, "template")], # template文件夹位置 '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', ], }, }, ]
Django静态文件配置程序员
文件路径 test_site -- test_site -- settings.pygithub
STATIC_URL = '/static/' # HTML中使用的静态文件夹前缀 STATICFILES_DIRS = [ os.path.join(BASE_DIR, "static"), # 静态文件存放位置 ]
看不明白?有图有真相:sql
刚开始学习时可在配置文件中暂时禁用csrf中间件,方便表单提交测试。数据库
文件路径 test_site -- test_site -- settings.pydjango
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为何要配置数据库
由于Django默认采用的是sqlite3数据库,而咱们用Pycharm编写程序时使用的是Pymysql模块和数据库交互的,为了可以简化编写程序的流程,咱们须要修改默认数据库配置
在修改数据配置以前,咱们是否是要先有数据库,请先建立一个MySQL数据库吧
文件路径 test_site -- test_site -- settings.py
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 注意这几个用大写的单词,必须写大写,这些坑我都走过,也浪费了很多时间,但愿你不要再走 'NAME': 'test_site', 'HOST': '127.0.0.1', 'PORT': 3306, 'USER': 'root', 'PASSWORD': '', # 个人数据库是没有密码的,你的密码是什么就写什么,没有就留空 } }
在和settings.py同目录下的 __init__.py文件中作配置
文件路径 test_site -- test_site -- __init__.py
import pymysql pymysql.install_as_MySQLdb()
至此,用Django写项目,相关的配置已完成,可是有一些关于Django的基础知识要学习,就像print同样简单,这也是咱们写项目的准备工做之一
HttpResponse 把数据返回给浏览器
这个模块名字起的特别好,根据名字就能大概猜出来的他的意思,真会起名字,不想某些人,写一套编程语言,用个什么蟒蛇,写个框架用个乐手的名字,真的是不为程序员着想
内部传入一个字符串,返回给浏览器,咱们在上一章的Hello World就是这么写的
def index(request): # 业务逻辑代码 return HttpResponse("Hello World")
render 对位填充
render 本意就是着色,粉刷的意思,很好理解,使用方式须要记住
除request参数外还接受一个待渲染的模板文件和一个保存具体数据的字典参数。
将数据填充进模板文件,最后把结果返回给浏览器。(相似于咱们上章用到的jinja2)
def index(request): # 业务逻辑代码 return render(request, "index.html", {"name": "Albert", "hobby": ["音乐", "篮球"]})
redirect 重定向
接受一个URL参数,表示跳转到指定的URL
注意:“” 里面的两个/ / 能少,不写会报错!注意:“” 里面的两个/ / 能少,不写会报错!注意:“” 里面的两个/ / 能少,不写会报错!
def index(request): # 业务逻辑代码 return redirect("/home/")
重定向实现原理
redirect 默认的302(临时重定向),30* 都是重定向,301是永久重定向,对于seo工程师用永久重定向比较多,若是要变为永久重定向,只须要
在redirect()里面增长这段代码便可
permanent=True
目标要求:
在完成以上配置以后,其实这个程序就已经写了一半了,是Django帮你写的,接下来真正的Python代码咱们只须要写函数和类,在实际的工做中,也是这样的
为了能让你们更清楚掌握用Django写程序的过程,接下来咱们按照过程前后带领你们把这个程序实现
开始项目
在终端下写入以下指令
# Django-admin startproject lms # cd lms # python3 manage.py startapp app01
固然以上操做你也能够在Pycharm上进行,彻底没有问题
建立数据库
注意数据库的名字,本身建立
修改配置
按照以上方法操做执行
创建url对应关系
在用户经过连接访问你的网站的时候,对于用户来讲这是一个连接地址,对于程序来时实际上是一个函数,经过这个函数才找到数据库中的对象,对象的方法和整个的前端页面
文件路径:和settings同目录下
"""lms 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 app01 import views urlpatterns = [ # 管理员帐户登录 url(r'^admin/', admin.site.urls), # 出版社列表 url(r'^publisher_list/', views.publisher_list), # 添加出版社 url(r'^add_publisher/', views.add_publisher), # 删除出版社 url(r'^drop_publisher/', views.drop_publisher), # 修改出版社 url(r'^edit_publisher/', views.edit_publisher), url(r'^book_list/', views.book_list), url(r'^add_book/', views.add_book), url(r'^drop_book/', views.drop_book), url(r'^edit_book/', views.edit_book), url(r'^author_list/', views.author_list), url(r'^add_author/', views.add_author), url(r'^drop_author/', views.drop_author), url(r'^edit_author/', views.edit_author), url(r'^$', views.publisher_list), # 只有跟网址,默认匹配 ]
建立对象,并关联数据库
找到app01这个文件夹,也就是项目应用的主文件夹下面有modes.py 文件,这个文件就是咱们用来存放类和对象的文件,这里须要用到ORM(对象关系映射),这里咱们先记住他的使用方法就行了,过几天带你们手写一个ORM。
注意:其余文件不要动,其余文件不要动,其余文件不要动
from django.db import models # Create your models here. # 出版社类 class Publisher(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=64) # 书籍的类 class Book(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=64) publisher = models.ForeignKey(to=Publisher) # Django中建立外键联表操做 # 做者的类 class Author(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=64) # 一个做者能够对应多本书,一本书也能够有多个做者,多对多,在数据库中建立第三张表 book = models.ManyToManyField(to=Book)
写核心逻辑函数
一样是app01文件夹下的views.py这个文件,上面的urls.py文件中的函数都是从这个文件中引入的,这个文件是最主要的文件
from django.shortcuts import render, redirect # Create your views here. from app01 import models # 出版社列表 def publisher_list(request): # 查询 publisher = models.Publisher.objects.all() # ORM中的查询所有 # 渲染 return render(request, 'publisher_list.html', {'publisher_list': publisher}) # 添加出版社 def add_publisher(request): # POST请求表示用户已提交数据 if request.method == 'POST': new_publisher_name = request.POST.get('name') models.Publisher.objects.create(name=new_publisher_name) return redirect('/publisher_list/') # 渲染待添加页面给用户 return render(request, 'add_publisher.html') # 删除出版社 def drop_publisher(request): # GET请求拿到url中的ID drop_id = request.GET.get('id') drop_obj = models.Publisher.objects.get(id=drop_id) drop_obj.delete() return redirect('/publisher_list/') # 编辑出版社 def edit_publisher(request): if request.method == 'POST': edit_id = request.GET.get('id') edit_obj = models.Publisher.objects.get(id=edit_id) new_name = request.POST.get('name') edit_obj.name = new_name # 注意保存 edit_obj.save() return redirect('/publisher_list/') edit_id = request.GET.get('id') edit_obj = models.Publisher.objects.get(id=edit_id) return render(request, 'edit_publisher.html', {'publisher': edit_obj}) # 书籍的列表 def book_list(request): book = models.Book.objects.all() return render(request, 'book_list.html', {'book_list': book}) # 添加本书籍 def add_book(request): if request.method == 'POST': new_book_name = request.POST.get('name') publisher_id = request.POST.get('publisher_id') models.Book.objects.create(name=new_book_name, publisher_id=publisher_id) return redirect('/book_list/') res = models.Publisher.objects.all() return render(request, 'add_book.html', {'publisher_list': res}) # 删除本书籍 def drop_book(request): drop_id = request.GET.get('id') drop_obj = models.Book.objects.get(id=drop_id) drop_obj.delete() return redirect('/book_list/') # 编辑本书籍 def edit_book(request): if request.method == 'POST': new_book_name = request.POST.get('name') new_publisher_id = request.POST.get('publisher_id') edit_id = request.GET.get('id') edit_obj = models.Book.objects.get(id=edit_id) edit_obj.name = new_book_name edit_obj.publisher_id = new_publisher_id edit_obj.save() return redirect('/book_list/') edit_id = request.GET.get('id') edit_obj = models.Book.objects.get(id=edit_id) all_publisher = models.Publisher.objects.all() return render(request, 'edit_book.html', {'book': edit_obj, 'publisher_list': all_publisher}) # 做者的列表 def author_list(request): author = models.Author.objects.all() return render(request, 'author_list.html', {'author_list': author}) # 添加个做者 def add_author(request): if request.method == 'POST': new_author_name = request.POST.get('name') models.Author.objects.create(name=new_author_name) return redirect('/author_list/') return render(request, 'add_author.html') # 删除个做者 def drop_author(request): drop_id = request.GET.get('id') drop_obj = models.Author.objects.get(id=drop_id) drop_obj.delete() return redirect('/author_list/') # 修改下做者 def edit_author(request): if request.method == 'POST': edit_id = request.GET.get('id') edit_obj = models.Author.objects.get(id=edit_id) new_author_name = request.POST.get('name') new_book_id = request.POST.getlist('book_id') edit_obj.name = new_author_name edit_obj.book.set(new_book_id) edit_obj.save() return redirect('/author_list/') edit_id = request.GET.get('id') edit_obj = models.Author.objects.get(id=edit_id) all_book = models.Book.objects.all() return render(request, 'edit_author.html', { 'author': edit_obj, 'book_list': all_book })
写前端页面
前端基本上是一直在重复的页面,注意几个与后端创建联系的地方就行了
<tbody> {% for publisher in publisher_list %} <tr> <td>{{ forloop.counter }}</td> <td>{{ publisher.name }}</td> <td class="text-center"> <a class="btn btn-info btn-sm" href="/edit_publisher/?id={{ publisher.id }}"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>编辑 </a> <a class="btn btn-danger btn-sm" href="/drop_publisher/?id={{ publisher.id }}"><i class="fa fa-trash-o fa-fw" aria-hidden="true"></i>删除 </a> </td> </tr> {% endfor %} </tbody>
前端复杂的部分是与数据库多表查询的部分,须要用for循环,注意for循环在Django中的使用方式
<select class="form-control" name="publisher_id"> {% for publisher in publisher_list %} {# 若是当前循环到的出版社 和 书关联的出版社 相等 #} {% if publisher == book.publisher %} <option selected value="{{ publisher.id }}">{{ publisher.name }}</option> {% else %} <option value="{{ publisher.id }}">{{ publisher.name }}</option> {% endif %} {% endfor %} </select>
完整代码已上传到GIthub,请点击个人github访问下载