本文详细介绍了Django框架,从入门到进阶,包括模型类、视图、模板、权限管理、中间件、缓存、Session、日志和RESTful接口。Django是一个功能强大的Python Web框架,适用于快速开发和管理后台站点。内容涵盖模型类创建、数据库配置、视图函数、模板渲染、表单处理、权限验证、Django REST Framework等,适合初学者和高级开发者参考学习。 摘要由CSDN通过智能技术生成

Django 框架是Python Web较早或历史较长,并且稳定、功能齐全的框架。

目前主要用于开发后台管理、服务运维站点平台、云计算运维平台及信息化管理系统等。

django框架适合初级开发人员,快速掌握和使用。对于高级开发人员来说,主要优化其不足的功能。

官方文档:https://docs.djangoproject.com/zh-hans/2.1/

django的重要的版本: 1.x(1.9/1.11), 2.x(2.1, 2.2, 2.3), 3.x(3.0, 3.1, 3.2)
请添加图片描述

一、Django 入门

【建议】每一个django项目,都有它自己的环境

1.1 安装

基于pip安装

pip install django==2.1

在交互的环境中,验证的django

>>> import django
>>> django.__version__

1.2 django-admin命令

1.2.1 创建项目命令
django-admin startproject mysite

项目结构说明:

  • 最外层的: 根目录只是你项目的容器, Django 不关心它的名字,你可以将它重命名为任何你喜欢的名字。
  • manage.py: 一个让你用各种方式管理 Django 项目的命令行工具。你可以阅读 django-admin and manage.py 获取所有 manage.py 的细节。
  • 里面一层的mysite/包含你的项目,它是一个纯 Python 包。它的名字就是当你引用它内部任何东西时需要用到的 Python 包名。 (比如 mysite.urls).
  • mysite/__init__.py:一个空文件,告诉 Python 这个目录应该被认为是一个 Python 包。如果你是 Python 初学者,阅读官方文档中的 更多关于包的知识
  • mysite/settings.py:Django 项目的配置文件。如果你想知道这个文件是如何工作的,请查看 Django settings 了解细节。
  • mysite/urls.py:Django 项目的 URL 声明,就像你网站的“目录”。阅读 URL调度器 文档来获取更多关于 URL 的内容。
  • mysite/wsgi.py:作为你的项目的运行在 WSGI 兼容的Web服务器上的入口。阅读 如何使用 WSGI 进行部署 了解更多细节。
  • 1.2.2 创建应用

    django项目的结构:由多个app组成的, 一个app即为一个模块。

    django中自带了 admin站点管理、session会话管理、log日志等app应用。

    django-admin startapp <应用名称>
    

    当项目创建成功之后,项目中包含了一个 manage.py脚本,可以执行此脚本也可以执行django-admin的命令。

    python manage.py startapp <应用名>
    

    应用目录结构:

    - migrations 包含所有生成当前应用的数据模型迁移文件脚本
    - apps.py  应用的配置信息
    - admin.py 配置站点下的应用信息    【一般】
    - models.py 应用的所有模型类声明所在的脚本 【重点】
    - tests.py 应用测试的脚本 
    - views.py 应用的所有Web接口  【重点】
    

    【重点】views和models的关系

    - Django采用 MVC设计思想,设计出自己的MTV
    - 在Views中,角色是Controller控制器, 通过Models将数据加载出来,再通过T(emplate)模板将数据渲染出来,最后将渲染后的HTML封装成Response响应对象返回给Django框架
    - models 数据模型, 采用了ORM框架,实现数据的CURD操作。同时支持模型之间的外键关联操作。
    
    1.2.3 运行服务
    python manage.py runserver 
    

    默认启动了 127.0.0.1:8000Web服务

    可以在runserver后面指定 端口:

    python manage.py runserver 9000
    

    可以指定ip的绑定的host:

    python manage.py runserver 0:9000
    

    0:表示为0.0.0.0:,绑定当前host主机的实际IP地址。

    在浏览器访问:

    - http://localhost:9000
    - http://127.0.0.1:9000
    - http://10.36.174.32:9000
    

    【注意】修改主工程目录下的settings.py文件

    ALLOWED_HOSTS = ['*']  # 白名单
    
    1.2.4 创建Web接口

    第一步:创建view处理函数

    from django.http import HttpResponse
    def index(request):
       return HttpResponse('hi, django')
    

    【说明】view处理函数的参数必须包含request,它是 WSGIRequest类的实例,也是HttpRequest的子类。可以从request对象中获取客户端请求的路径以及请求头和body数据。

    第二步: 配置路由

    方式1: 直接在主路由中配置(主工程包/urls.py)

    from login.views import index
    from django.urls import path
    from django.contrib import admin  # 自带的admin应用
    urlpatterns = [
        path('', index),
        path('admin/', admin.site.urls),
    

    方式2:创建应用的子路由urls.py(复制主路由的urls.py)

    from .views import index
    from django.urls import path
    urlpatterns = [
        path('', index),
    

    使用子路由时,必须要做2件事件:

    - 将应用模块 添加到 settings.py中的INSTALLED_APPS 列表中 [实际上不需要]
    - 将子路由添加到主路由中
    

    修改主urls.py

    from django.contrib import admin
    from django.urls import path, include
    urlpatterns = [
        path('user/', include('login.urls')),
        path('admin/', admin.site.urls),
    
    1.2.5 创建模型类

    第一步:配置数据库

    采用默认的数据库 sqlite3

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    

    第二步: 创建模型类

    from django.db import models
    # Create your models here.
    class User(models.Model):
        # 默认情况下 存在 id主键
        user_id = models.IntegerField(primary_key=True)
        name = models.CharField(max_length=20, unique=True)
        pwd = models.CharField(max_length=100)
    

    第三步: 配置INSTALLED_APPS

    INSTALLED_APPS = [
        ...
        'django.contrib.staticfiles',
        'login',
    

    login是应用名

    第四步: 生成数据表(模型类)的迁移文件

    python manage.py makemigrations
    

    【注意】确认模型类所在的app是否已添加到settings.py的INSTALLED_APPS列表中。

    第五步: 执行数据模型类的迁移文件

    python manage.py migrate
    

    【注意】第一次迁移时,会自动迁移django自带app下的迁移文件.

    【重要】如果修改了模型类, 必须要makemigrationsmigrate

    1.2.6 shell调试模型

    进入django shell中

    python manage.py shell
    
    >>> from login.models import User
    >>> User.objects.all()  
    

    【注意】objects是什么?

    - objects是Model的元类中创建Manage类实例, 也是QuerySet查询结果类实例
    - objects提供了对模型的查询相关方法 【非常重要】
    
    1.2.7 模型类操作
    User.objects.all() 查询所有的数据,返回可迭代的对象(QuerySet实例),元素是模型类的实例对象。
    

    QuerySet实例方法

    - all()
    - first()
    - last()
    - get(属性名=属性值)  # pk主键列名属性
    - delete() # 模型类的实例对象
    - filter(属性名=属性值)
    - count() 统计记录个数
    

    创建模型类实例

    u1 = User(name="disen", pwd="123", phone="17791692095")
    u2 = User()
    u2.name="jack"
    u2.pwd="123"
    u2.phone="18999971112"
    

    模型类实例方法

    - save() 保存数据
    - delete() 删除数据
    - refresh_from_db() 同步数据(从数据库的表中更新当前实例的属性)
    
    1.2.8 admin站点管理

    参考文档:https://docs.djangoproject.com/zh-hans/2.1/ref/contrib/admin/

    django本身提供了admin站点管理应用, 在每一个app中提供了admin.py脚本,可以将当前应用的models.py中模型类,添加到admin站点中,以方便管理员管理模型对应的数据。

    第一步: 创建后台管理员账号(超级管理员)

    python manage.py createsuperuser
    >> username:  admin
    >> email:  610039018@qq.com
    >> password: admin123
    >> password (again): admin123
    >> Bypass password validation and create user anyway? [y/N]: :y
    

    启动服务之后,可以访问/admin进入站点后台管理页面。

    可以尝试创建后台管理人员账号, 将activestaff status勾选上。并添加login应用的管理User模型的权限。

    第二步:将login应用中的模型类添加到admin.py中

    from django.contrib import admin
    from .models import User
    # @admin.register(User)
    class UserAdmin(admin.ModelAdmin):
        list_display = ('user_id', 'name', 'phone', 'email')
        list_display_links = ('name', )
        list_filter = ('name', 'phone')
        list_editable = ('phone', 'email')
        search_fields = ('name', 'phone', 'email')
    admin.site.register(User, UserAdmin)
    

    修改模型类:

    主要添加Field字段参数的blank和verbose_name

    class User(models.Model):
        # 默认情况下 存在 id主键
        user_id = models.IntegerField(primary_key=True, blank=True,verbose_name='用户ID')
        name = models.CharField(max_length=20, unique=True,verbose_name='用户名')
        pwd = models.CharField(max_length=100, verbose_name='口令')
        # 添加手机号和邮箱
        phone = models.CharField(max_length=11, null=True, verbose_name='手机'
    
    
    
    
        
    , blank=True)
        email = models.CharField(max_length=50, null=True, verbose_name='邮箱', blank=True)
        def __str__(self):
            return f'{
         self.user_id } <{
         self.name}>'
        class Meta:
            verbose_name = 'Vip会员'
            verbose_name_plural = verbose_name
    
    【站点中显示app应用的中文名称】

    第一步:在xxx app的__init__.py文件中,添加如下代码:

    # 自模块下的AppConfig的子类
    default_app_config = 'testingapp.apps.TestingappConfig'
    

    第二步:在TestingappConfig中添加verbose_name属性

    class TestingappConfig(AppConfig):
        name = 'testingapp'
        verbose_name = '自动化测试'
    
    1.2.9 配置多数据库

    一个django项目,可以存在多个数据库连接,在settings.py的DATABASES字典对象中配置,如下所示:

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'db1': {
           'ENGINE': 'django.db.backends.mysql',
           'HOST': '180.76.121.47',
           'PORT': 3306,
           'USER': 'root',
           'PASSWORD': 'rootxaqf2101',
           'NAME': 'testdb'
     
    

    django-admin或manager.py中提供了 inspectdb命令,可以将已存在的表生成模型类,命令如下:

    python manager.py inspectdb --database db1 > testingapp/models.py
    

    连接db1数据库,将库中所有表全部生成模型类,并写入到testingapp应用下的models.py脚本中。

    1.2.11 重写Manager

    由于,模型类操作时,默认选择default数据库,因此需要重新指定模型类的objects实例的类型,需要先声明一个models.Manager类的子类,并重写get_queryset()方法,如下:

    class DB1Manager(models.Manager):
        def get_queryset(self):
            return self._queryset_class(model=self.model, using='db1', hints=self._hints)
    

    之后,在模型类中,显式地增加objects成员,如下:

    class TbPerson(models.Model):
        person_id = models.IntegerField(primary_key=True, verbose_name='ID')
        phone = models.CharField(max_length=11, blank=True, null=True, verbose_name='手机号')
        # ... 省略
        objects = DB1Manager() # 指定using为db1数据库的查询集实例
        class Meta:
            managed = False
            db_table = 'tb_person'
            verbose_name_plural = verbose_name = '人员信息'
    
    1.2.12 重写模型类之save

    对于模型类拥有objects成员,只能用于查询和修改,如果是新增,则需要重写save方法,保证数据写入到正确的数据库中。

    class TbPerson(models.Model):
        person_id = models.IntegerField(primary_key=True, verbose_name='ID')
        phone = models.CharField(max_length=11, blank=True, null=True, verbose_name='手机号')
        # ... 省略
        objects = DB1Manager() 
         def save(self, force_insert=False, force_update=False, using=None,
                 update_fields=None):
            return super(TbPerson, self).save(using='db1')
        class Meta:
            managed = False
            db_table = 'tb_person'
            verbose_name_plural = verbose_name = '人员信息'
    

    1.3 views视图与模板

    1.3.1 请求路径参数
    from .views import index, update_user
    urlpatterns = [
        path('', index),
        path('<user_id>/', update_user)
    
    def update_user(request, user_id):
        return HttpResponse('修改用户ID:%s' % user_id)
    
    1.3.2 模板配置

    首先在项目的根目录下,创建一个templates目录,并在settings.py的TEMPLATES配置DIRS模板路径,如下:

    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.3.3 创建模板的html文件
    <!DOCTYPE html>
    <html lang="en">
        <meta charset="UTF-8">
        <title>更新用户</title>
    </head>
      { user.name }} 用户信息修改</h3>
    </body>
    </html>
    
    1.3.4 在views渲染模板

    在templates目录下创建

    def update_user(request, user_id):
        # 通过模型将user_id对应的数据表的数据加载到
        user = User.objects.get(pk=user_id)
        # 将数据渲染到模板中,并返回HttpResponse对象
        # render(request, template_name, context= {})
        resp = render(request, 'update.html', {
       'user': user})
        return resp
    

    【练习】查看所有用户信息,显示到模板上

    def view_users(request):
        # 获取所有的用户信息
        users = User.objects.all()
        return render(request, 'user_list.html', {
       'users': users})
    
    <!DOCTYPE html>
    <html lang="en">
        <meta charset="UTF-8">
        <title>用户列表</title>
    </head>
    <h3>查询用户结果</h3>
        {% for u in users %}
      { u.id }} - {
      { u.name }} - {
      { u.phone }} </li>
        {% endfor %}
    </body>
    </html>
    
    from django.urls import path
    from .views import index,update_user, view_users
    urlpatterns = [
        path('', index),
        path('<int:user_id>/', update_user),
        path('list/', view_users )
    

    【Http404】抛出404异常

    def update_user(request, user_id):
        # 通过模型将user_id对应的数据表的数据加载到
        try:
            user = User.objects.get(pk=user_id)
        except User.DoesNotExist:
            raise Http404('未找到 {}'.format(user_id))
        # 将数据渲染到模板中,并返回HttpResponse对象
        # render(request, template_name, context= {})
        resp = render(request, 'update.html', {
       'user': user})
        return resp
    
    from django.shortcuts import render, get_object_or_404
    def update_user(request, user_id):
        user = get_object_or_404(User, pk=user_id)
        resp = render(request, 'update.html', {
       'user': user})
        return resp
    
    1.3.5 模板的url指令

    第一步: 在路由中声明url路径时,可以指定name属性(path())

    path('<int:user_id>/', update_user, name='update'),
    path('list/', view_users, name='ulist')
    

    第二步:在template模板文件中

    <a href="{% url 'ulist' %}">查看所有用户</a>
    

    【重要】{% url %} 指令是反向查找路径,好处,无论url路径如何修改,都可以反向获取完整的请求路径。另外格式可以带有namespace:

     <a href="{% url 'user:ulist' %}">查看所有用户</a>
    

    user:代表是include()方法中指定的namespace属性值。

    主路由中添加子路由时,可以同时指定的namespace

    urlpatterns = [
        path('user/', include('login.urls', namespace='user')),
        path('admin/', admin.site.urls),
    

    但是在子路由urls.py文件中,必须指定app_name应用名称。

    app_name = 'user'
    urlpatterns = [
        path('', index),
        path('<int:user_id>/', update_user, name='update'),
        path('user_list/', view_users, name='ulist')
    

    1.4 form表单提交

    1.4.1 修改模板
    <!DOCTYPE html>
    <html lang=
    events = generic.GenericRelation('Event') 通过这个字段可以得到与某篇post相关联的所有事件,最重要的一点是如果没有这个字段,那么当删除一篇post的时候,与该post关联的事件是不会自动删除的。反之有这个字段就会进行自动的级联删除。 from django.db.models.signals import post_save from dja
    一、Django 框架介绍 Django 框架始于 2003 年,是由美国堪萨斯州劳伦斯的《世界日报》的 Adrian Holovaty 和 Simon Willison 完成的一个项目。2005 年,Holovaty 和 Willison 发布了该框架的第一个公开版本,并以比利时-法国吉他手坦哥·雷恩哈特的名字命名。 快进到 2017 年——Django 框架现在在 Django 软件基金会(DSF)的指导下运行,框架核心有
    在Web应用中,通常有一些业务功能模块是在不同的项目中都可以复用的,故在开发中通常将工程项目拆分为不同的子功能模块,各功能模块间可以保持相对的独立,在其他工程项目中需要用到某个特定功能模块时,可以将该模块代码整体复制过去,达到复用。 1、创建子应用 python manage.py startapp 子应用名称 #manage.py是创建工程时自动生成的管理文件 例如,在刚才创建的bookm...
    在前端工具-自定义generator文章中,介绍了如何自定义generator模块,以及生成对应的文件,如果是一个接一个写文件的话 比较费力,好在我们有模板语法通过模板语法,大大提高了效率 const Generator = require('yeoman-generator'); module.exports = class extends Generator { //通过模板的方式写入文件到目标目录 模板内部自动使用EJS语法 //模板路径 Django是一个开放源代码的Web应用框架,由Python语言写成,采用了MVT的框架模式,即模型M、视图V和模板T。 MVT全名是ModelViewTemplate,而Python的Web开发框架Django是属于MVT模式。实际上,Django的MVT模式本质上与MVC模式基本没有什么差别,它也是各组件之间为了保持松耦合关系,只是定义上有一些不同,Django的MVT分别代表如下: M是Model的简称,与MVC中的M功能相同,主要用于负责和数据库交.
    1.2.10 反向生成模型