简介
Django是一个主流的Python Web框架,用于快速开发 Web 应用程序。功能强大,Python Web应用开发的第一选择。
特点
-
ORM(对象关系映射): Django 提供了一个强大的 ORM,允许开发者通过 Python 代码来定义和操作数据库模型,而无需直接使用 SQL。这使得数据库操作更加抽象和易于管理。
-
MVC 架构: Django 遵循 MVC(模型-视图-控制器)的软件设计模式,但它使用了稍微不同的术语。在 Django 中,模型(Model)表示数据结构,视图(View)负责呈现用户界面,而控制器(Controller)的职责被称为视图(View)。
-
模板引擎: Django 使用模板引擎来生成 HTML,这使得前端和后端的代码分离更加容易。Django 的模板语言允许开发者在模板中嵌入动态内容。
-
自动化 admin 界面: Django 自动生成管理后台,使得管理和操作数据库的过程变得非常简单。开发者可以轻松地创建、修改和删除数据库记录,而无需编写自定义的管理界面。
-
表单处理: Django 提供了强大的表单处理工具,使得用户输入的验证和处理变得更加简单。这对于开发 Web 表单和处理用户提交的数据非常有用。
-
安全性: Django 内置了一些安全性功能,例如防止常见的 Web 攻击(如 CSRF 攻击),并提供了方便的用户身份验证和授权系统。
-
可扩展性: Django 的组件是松耦合的,允许开发者使用现有的组件或编写自己的应用程序来扩展框架功能。
-
社区支持: Django 拥有庞大的社区支持,提供了大量的文档、教程和第三方包,使得学习和使用 Django 变得更加容易。
MVC 与 MTV模型
MVC 模型
MVC 模式(Model--view--controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。
MVC 以一种插件式的、松耦合的方式连接在一起。
- 模型(M)- 编写程序应有的功能,负责业务对象与数据库的映射(ORM)。
- 视图(V)- 图形界面,负责与用户的交互(页面)。
- 控制器(C)- 负责转发请求,对请求进行处理。
简易图:
用户操作流程图:
MTV 模型
Django 的 MTV 模式本质上和 MVC 是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django 的 MTV 分别是指:
- M 表示模型(Model):编写程序应有的功能,负责业务对象与数据库的映射(ORM)。
- T 表示模板 (Template):负责如何把页面(html)展示给用户。
- V 表示视图(View):负责业务逻辑,并在适当时候调用 Model和 Template。
除了以上三层之外,还需要一个 URL 分发器,它的作用是将一个个 URL 的页面请求分发给不同的 View 处理,View 再调用相应的 Model 和 Template,MTV 的响应模式如下所示:
简易图:
用户操作流程图:
解析:
用户通过浏览器向我们的服务器发起一个请求(request),这个请求会去访问视图函数:
- a.如果不涉及到数据调用,那么这个时候视图函数直接返回一个模板也就是一个网页给用户。
- b.如果涉及到数据调用,那么视图函数调用模型,模型去数据库查找数据,然后逐级返回。
视图函数把返回的数据填充到模板中空格,最后返回网页给用户。
安装Django
本教程使用的是Python3.11,Django5.0。
使用Django需要安装Python环境,如果你还没有安装 Python,请先从 Python 官网Download Python | Python.org下载并安装最新版本的 Python。
如果你还不懂Python,去这里学习Python基础:Python从入门到精通
安装django非常容易,一行代码搞定:
pip install django -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
验证一下是否安装成功,看到版本号表示ok:
python -m django --version
好的,我们已经安装好了Django,接下来我们正式进行Django开发。
创建一个Django项目
django-admin startproject mysite
执行后会生成如下项目结构
mysite
|-- mysite
| |-- __init__.py
| |-- asgi.py
| |-- settings.py
| |-- urls.py
| `-- wsgi.py
`-- manage.py
- mysite : 项目的容器。
- manage.py: 一个实用的命令行工具,可让你以各种方式与该 Django 项目进行交互。
- mysite/init.py: 一个空文件,告诉 Python 该目录是一个 Python 包。
- mysite/asgi.py: 一个 ASGI 兼容的 Web 服务器的入口,以便运行你的项目。
- mysite/settings.py: 该 Django 项目的设置/配置。
- mysite/urls.py: 该 Django 项目的 URL 声明; 一份由 Django 驱动的网站"目录"。
- mysite/wsgi.py: 一个 WSGI 兼容的 Web 服务器的入口,以便运行你的项目。
接着我们进入 mysite 目录输入以下命令,启动服务器:
python manage.py runserver
注意:默认端口为8000,你也可以指定你的ip和端口,例如:python manage.py runserver ip port
好了现在你已经启动了django项目,在浏览器访问 127.0.0.1:8000 就会看到django的默认页面。
接下来我们开发一个用户管理案例,结合MySQL+Bootstrap+jQuery完成用户的增删改查。
django5.0需要安装MySQL8.0+,请确保你已经安装了MySQL8.0+
用户管理案例
基于mysite项目创建app
1.创建应用程序
python manage.py startapp ums
模板文件和静态文件进行分开管理,便于维护。按照如下创建:
确保你的目录命名一定是templates和static,否则django容器加载不到。
2.数据库配置
在mysite/settings.py文件中配置你的MySQL连接信息
python
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'ums',
'HOST': '127.0.0.1',
'PORT': 3306,
'USER': 'root',
'PASSWORD': '123456',
}
}
3.下载mysqlclient
mysqlclient作为django与MySQL的桥梁,负责数据的操作和持久化。通过mysqlclient来初始化表结构。
python
pip install mysqlclient
4.定义模型
在 ums/models.py 放入以下内容
python
class UserInfo(models.Model):
username = models.CharField(verbose_name='用户名', max_length=32)
password = models.CharField(verbose_name='密码', max_length=64)
age = models.IntegerField(verbose_name='年龄')
salary = models.DecimalField(verbose_name='工资', max_digits=10, decimal_places=2)
gender_choices =(
(1, '男'),
(2, '女')
)
gender = models.SmallIntegerField(verbose_name='性别', choices=gender_choices)
create_time = models.DateTimeField(verbose_name='创建时间')
数据库表初始化
python
$ python manage.py makemigrations
$ python manage.py migrate
5、编写视图
在 ums/views.py 编写用户增删改查
python
def user_list(request):
""" 查询用户列表 """
# 获取所有用户列表 [obj,obj,obj]
queryset = models.UserInfo.objects.all()
return render(request, 'user_list.html', {'queryset': queryset})
def user_add(request):
""" 添加用户 """
if request.method == "GET":
context = {
'gender_choices': models.UserInfo.gender_choices,
"dept_list": models.Department.objects.all()
}
return render(request, 'user_add.html', context)
# 获取用户提交的数据
user = request.POST.get('username')
pwd = request.POST.get('pwd')
age = request.POST.get('age')
salary = request.POST.get('salary')
ctime = request.POST.get('ctime')
gender = request.POST.get('gd')
dept = request.POST.get('dp')
# 添加到数据库中
models.UserInfo.objects.create(username=user, password=pwd, age=age,
salary=salary, create_time=ctime,
gender=gender, dept_id=dept)
# 返回到用户列表页面
return redirect("/user/list/")
def user_delete(request, nid):
""" 删除用户 """
models.UserInfo.objects.filter(id=nid).delete()
return redirect('/user/list/')
def user_edit(request, nid):
""" 编辑用户 """
row_object = models.UserInfo.objects.filter(id=nid).first()
if request.method == "GET":
# 根据ID去数据库获取要编辑的那一行数据(对象)
form = UserModelForm(instance=row_object)
return render(request, 'user_edit.html', {'form': form})
form = UserModelForm(data=request.POST, instance=row_object)
if form.is_valid():
# 默认保存的是用户输入的所有数据,如果想要再用户输入以外增加一点值
# form.instance.字段名 = 值
form.save()
return redirect('/user/list/')
return render(request, 'user_edit.html', {"form": form})
from django import forms
class UserModelForm(forms.ModelForm):
username = forms.CharField(min_length=3, label="用户名")
class Meta:
model = models.UserInfo
fields = ["username", "password", "age", 'salary', 'create_time', "gender", "dept"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 循环找到所有的插件,添加了class="form-control"
for name, field in self.fields.items():
field.widget.attrs = {"class": "form-control", "placeholder": field.label}
6、编写模板
templates下编写模板
user_list.html
html
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<div style="margin-bottom: 10px">
<a class="btn btn-success" href="/user/add/">
<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
新建用户
</a>
</div>
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">
<span class="glyphicon glyphicon-th-list" aria-hidden="true"></span>
用户列表
</div>
<!-- Table -->
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>用户名</th>
<th>密码</th>
<th>年龄</th>
<th>工资</th>
<th>创建时间</th>
<th>性别</th>
<th>所属部门</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for obj in queryset %}
<tr>
<th>{{ obj.id }}</th>
<td>{{ obj.name }}</td>
<td>{{ obj.password }}</td>
<td>{{ obj.age }}</td>
<td>{{ obj.salary}}</td>
<td>{{ obj.create_time|date:"Y-m-d" }}</td>
<td>{{ obj.get_gender_display }}</td>
<td>{{ obj.dept.name}}</td>
<td>
<a class="btn btn-primary btn-xs" href="/user/{{ obj.id }}/edit/">编辑</a>
<a class="btn btn-danger btn-xs" href="/user/{{ obj.id }}/delete/">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %}
user_add.html
html
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"> 新建用户 </h3>
</div>
<div class="panel-body">
<form method="post">
{% csrf_token %}
<div class="form-group">
<label>用户名</label>
<input type="text" class="form-control" placeholder="姓名" name="username" />
</div>
<div class="form-group">
<label>密码</label>
<input type="text" class="form-control" placeholder="密码" name="pwd"/>
</div>
<div class="form-group">
<label>年龄</label>
<input type="text" class="form-control" placeholder="年龄" name="age"/>
</div>
<div class="form-group">
<label>余额</label>
<input type="text" class="form-control" placeholder="工资" name="salary"/>
</div>
<div class="form-group">
<label>创建时间</label>
<input type="text" class="form-control" placeholder="创建时间" name="ctime"/>
</div>
<div class="form-group">
<label>性别</label>
<select class="form-control" name="gd">
{% for item in gender_choices %}
<option value="{{ item.0 }}">{{ item.1 }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label>部门</label>
<select class="form-control" name="dp">
{% for item in dept_list %}
<option value="{{ item.id }}">{{ item.name}}</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-primary">提 交</button>
</form>
</div>
</div>
</div>
{% endblock %}
user_edit.html
html
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"> 编辑用户 </h3>
</div>
<div class="panel-body">
<form method="post" novalidate>
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label>{{ field.label }}</label>
{{ field }}
<span style="color: red;">{{ field.errors.0 }}</span>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">提 交</button>
</form>
</div>
</div>
</div>
{% endblock %}
layout.html
html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
<style>
.navbar {
border-radius: 0;
}
</style>
</head>
<body>
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#"> 用户管理系统 </a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="/user/list/">用户管理</a></li>
<li><a href="#">Link</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">登录</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Johnny<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">个人资料</a></li>
<li><a href="#">我的信息</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">注销</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<div>
{% block content %}{% endblock %}
</div>
<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}"></script>
</body>
</html>
7、配置路由
在 mysite/urls.py 配置路由
python
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
# 用户管理
path('user/list/', views.user_list),
path('user/add/', views.user_add),
path('user/<int:nid>/edit/', views.user_edit),
path('user/<int:nid>/delete/', views.user_delete),
]
最后启动程序,恭喜您,完成!
python
python manage.py runserver