目录

Django 入门教程|Web开发|用户管理实战

简介

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
本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
2401_878454531 小时前
Themeleaf复用功能
前端·学习
与己斗其乐无穷2 小时前
刷题记录(3)C语言中的字符
c语言·学习
失去妙妙屋的米奇4 小时前
matplotlib数据展示
开发语言·图像处理·python·计算机视觉·matplotlib
搞不懂语言的程序员4 小时前
备忘录模式深度解析与实战案例
数据库·python·备忘录模式
十年之少5 小时前
异步编程——微信小程序
笔记·学习·微信小程序
爱的叹息5 小时前
关于 JDK 中的 jce.jar 的详解,以及与之功能类似的主流加解密工具的详细对比分析
java·python·jar
L小李要学习5 小时前
STM32学习
stm32·嵌入式硬件·学习
Lhuu(重开版5 小时前
2025第十六届蓝桥杯PythonB组部分题解
python
来自星星的坤5 小时前
SpringBoot 与 Vue3 实现前后端互联全解析
后端·ajax·前端框架·vue·springboot
Q186000000005 小时前
PDF解析示例代码学习
学习·pdf