Django 3.0 中文官方文档项目实战

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:本项目为Django Web框架的3.0版本中文文档,详尽介绍了Django的使用方法、API参考、最佳实践和常见问题解答。包含了构建信息、模块索引、目录结构、术语解释、全文搜索功能等关键文档部分。通过这些内容,开发者可以深入学习Django的安装、配置、模型、视图、模板、URL设置、表单、中间件、命令管理、数据库操作、缓存系统、性能优化、测试及部署等核心功能。 Django

1. Django框架的诞生与架构精髓

1.1 Django的诞生背景

Django是由一个新闻编辑团队为了解决日常工作中遇到的项目问题而创造的。它的起源可以追溯到2003年,由Adrian Holovaty和Simon Willison领导的Python开发团队在Lawrence Journal-World报社开发内容管理系统时,为了提高开发效率和质量,开始编写Django的早期版本。

1.2 架构的MVC模式

Django采用了MVC(Model-View-Controller)模式,但将其调整为更加直观和合理的MVT(Model-View-Template)模式。这种模式的优点在于它将Web应用的业务逻辑、显示逻辑以及数据处理逻辑清晰地分离开来,使得代码更加模块化,便于维护和扩展。

1.3 面向对象设计原则

Django框架的设计遵循了面向对象编程的SOLID原则,强调高内聚低耦合。通过强大的内置组件和抽象层,它提供了丰富的接口供开发者使用,同时也保证了代码的可复用性和可扩展性。

1.4 架构精髓:Django的高级特性

Django的高级特性包括内置的用户认证系统、内容管理框架、国际化支持等。这些特性大大减少了重复工作,提升了开发效率,并保障了项目的安全性与可维护性。例如,Django的用户认证系统不仅支持用户注册、登录、密码找回等基本功能,还支持扩展的权限管理,可以根据用户的角色分配不同的操作权限。

2. Django基础操作与模型构建

2.1 Django项目初始化与配置

创建Django项目

Django项目的创建是开始使用Django框架的第一步。在创建项目时,Django提供了一个非常简便的命令行工具来帮助开发者初始化项目结构和配置。

django-admin startproject mysite

上述命令中, mysite 是项目名称,可以替换为任意你想要的名字。执行该命令后,Django会在当前目录下创建一个名为 mysite 的新文件夹,其中包含一个初始的Django项目结构。

接下来,进入该目录并启动开发服务器以确保一切配置正确。

cd mysite
python manage.py runserver

如果你看到控制台输出类似于 "Starting development server at ***" 的信息,那么你的Django项目已经成功启动,并且可以通过浏览器访问指定地址查看效果。

理解项目结构与设置

在初始化项目后,Django会创建一个默认的项目结构。理解这个结构对于后续开发至关重要。

项目的根目录一般包含以下主要文件和文件夹: - manage.py :Django项目管理文件,提供了运行Django项目所需的管理命令。 - mysite/ :一个Python包,代表你的Django项目。 - mysite/__init__.py :表明这个目录是一个Python包。 - mysite/settings.py :包含Django项目的设置和配置。 - mysite/urls.py :项目的URL声明,相当于项目的导航地图。 - mysite/wsgi.py :作为项目的入口点,用于生产环境中的Web服务器通信。

为了理解每个文件的作用,我们可以通过修改设置来观察项目行为的变化。例如,打开 settings.py 文件,找到 LANGUAGE_CODE 设置,修改为一个错误的语言代码:

LANGUAGE_CODE = 'en-usa'

保存文件后,再次启动开发服务器并访问首页,你会看到一个错误页面,因为 LANGUAGE_CODE 的值不正确。通过这个过程,你可以加深对Django设置的理解。

2.2 Django模型层的设计与应用

设计数据库模型

Django通过模型(Models)来定义与数据库交互的数据结构。模型基于Python类,每个模型都对应数据库中的一张表。

设计模型通常从定义模型类开始。每个类都继承自 django.db.models.Model ,并且每个类的属性都映射为数据库表的列。

from django.db import models

class MyModel(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField()

在这个例子中,我们创建了一个简单的模型 MyModel ,包含两个字段: name description name 是字符字段, description 是文本字段。

数据迁移与模型操作实践

定义好模型之后,Django需要将这些定义转化为数据库中的表结构。这一步通过数据迁移完成。

首先,创建模型的初始迁移文件:

python manage.py makemigrations

Django会分析模型定义,创建迁移文件。接下来,将这些更改应用到数据库:

python manage.py migrate

这个命令会应用所有的迁移文件到数据库中。此时,数据库会根据模型定义创建对应的表。

一旦模型创建并迁移完成,你就可以开始进行数据操作了。Django提供了一套ORM(对象关系映射)系统,允许我们用Python代码进行数据操作。

from myapp.models import MyModel

# 创建对象实例
obj = MyModel(name='Sample Name', description='Sample Description')
obj.save()

# 查询对象
all_objects = MyModel.objects.all()

# 更新对象
obj = all_objects.first()
obj.name = 'New Name'
obj.save()

# 删除对象
obj.delete()

在实际应用中,模型层的设计会涉及到更复杂的概念,如关系、索引、默认值等。理解这些基础知识对于进一步学习Django模型层是至关重要的。

2.3 Django视图和URL配置

构建视图逻辑

Django视图是处理用户请求并返回响应的对象。视图逻辑通常位于应用目录的 views.py 文件中。创建视图需要继承 django.http.HttpResponse 类。

from django.http import HttpResponse

def home(request):
    return HttpResponse("Hello, Django!")

在上面的代码中,我们创建了一个简单的视图 home ,当访问这个视图时,它会返回一个字符串 "Hello, Django!"。

将视图与URL关联是通过在应用的 urls.py 文件中编写URL模式实现的。首先需要从 django.urls 导入 path 函数和视图模块。

from django.urls import path
from . import views

urlpatterns = [
    path('home/', views.home, name='home'),
]

在这个例子中,我们使用了 path 函数来创建一个路由,这个路由会将 /home/ URL 路径关联到 home 视图函数。 name='home' 是一个命名参数,可以在模板中引用这个URL。

URL路由与视图映射

为了提高路由的可管理性,我们通常会在应用中创建一个专门的 urls.py 文件,并在项目的主 urls.py 文件中包含它。

# myapp/urls.py
urlpatterns = [
    # ... 其他路由配置 ...
]

# mysite/urls.py
from django.urls import include, path

urlpatterns = [
    path('myapp/', include('myapp.urls')),
]

在上面的例子中, include 函数允许你引用应用的 urls.py 文件。当用户访问 /myapp/ 时,Django 会将请求转发给 myapp 应用的URL配置。

通过合理设计URL路由,可以使得项目结构清晰,易于管理。此外,Django还支持动态路由,可以捕获URL中的动态部分并将其作为参数传递给视图函数。这在构建动态网站时非常有用。

至此,我们已经了解了Django基础操作与模型构建的关键部分。下一章节我们将深入探讨Django模板系统与表单处理,这些都是构建动态Web应用不可或缺的功能。

3. Django模板系统与表单处理

3.1 Django模板语言深入

3.1.1 模板继承与包含机制

在Web开发中,模板继承和包含机制是一项重要的特性,它允许开发者创建可重用的模板组件,并在多个页面中应用,从而提高开发效率和维护性。Django模板语言(DTL)提供了一套完整的继承与包含机制,使得模板更加模块化。

首先,创建一个基础模板(base.html),它将作为整个项目模板的根基:

<!-- base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}My Website{% endblock %}</title>
</head>
<body>
    {% block content %}
    <!-- 页面内容将被插入到这里 -->
    {% endblock %}

    {% block extra_content %}
    <!-- 可选的额外内容区域 -->
    {% endblock %}
</body>
</html>

在上面的代码中, {% block %} 标签定义了模板的可扩展区域。子模板可以通过填充这些块来覆盖或者扩展父模板的内容。

接下来,创建一个继承自 base.html 的模板(home.html),它添加了特定页面的内容:

<!-- home.html -->
{% extends "base.html" %}

{% block title %}Home Page{% endblock %}

{% block content %}
<h1>Welcome to the Home Page</h1>
<p>This is the content specific to the home page.</p>
{% endblock %}

{% block extra_content %}
<p>Extra content here if needed.</p>
{% endblock %}

在这个例子中, {% extends "base.html" %} 指令明确告诉Django, home.html 继承自 base.html 。在 home.html 中, title content extra_content 块被重新定义,以提供特定的内容。

3.1.2 模板标签和过滤器的高级用法

Django模板语言不仅支持继承和包含机制,还提供了大量的标签和过滤器,用于控制模板逻辑和格式化数据。高级用法可以极大地增强模板的动态性和灵活性。

标签(Tags) 是执行操作的模板代码,它们可以输出内容、控制循环和条件逻辑等。例如, for 标签可以遍历一个列表:

{% for item in items %}
    <li>{{ item }}</li>
{% endfor %}

过滤器(Filters) 用于对数据进行格式化处理。过滤器可以链式使用,以实现复杂的数据转换:

{{ my_date|date:"Y-m-d" }} <!-- 格式化日期 -->
{{ text|truncatewords:30 }} <!-- 限制文本为30个单词 -->

Django模板还支持自定义标签和过滤器,以及使用第三方扩展,为模板系统增添了极大的灵活性和扩展性。

3.2 Django表单的创建与验证

3.2.1 构建自定义表单

Django的表单系统是构建Web应用中不可或缺的部分。Django表单不仅处理HTML表单的呈现,还能处理数据的清洗和验证。

创建一个自定义表单类通常涉及继承 forms.Form ,并定义表单字段:

from django import forms

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    email = forms.EmailField()
    message = forms.CharField(widget=forms.Textarea)

在视图中使用这个表单,需要创建一个表单实例,并在模板中渲染它:

# views.py
from django.shortcuts import render
from .forms import ContactForm

def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            # 处理表单数据
            pass
    else:
        form = ContactForm()
    return render(request, 'contact.html', {'form': form})

3.2.2 表单验证逻辑和消息处理

当表单被提交后,Django会自动调用 is_valid() 方法来处理数据清洗和验证。开发者可以自定义字段的验证逻辑:

# forms.py
from django.core.exceptions import ValidationError

def validate_email_domain(value):
    if not value.endswith('@***'):
        raise ValidationError('Please use a valid email domain.')

class ContactForm(forms.Form):
    # ... 其他字段定义 ...
    email = forms.EmailField(validators=[validate_email_domain])

如果表单数据验证失败,Django会存储错误信息。在模板中,可以使用 {{ form.errors }} 来显示这些错误信息,帮助用户理解需要修正的地方。

处理完表单逻辑后,通常需要给用户一个反馈,如发送确认邮件、显示感谢页面等。这些反馈通过视图的逻辑进行处理,并通过模板呈现给用户。

接下来是进一步深入探讨Django模板系统的高级特性与表单处理,通过实际案例和代码示例,我们不仅可以了解模板和表单的理论知识,还能掌握它们在实际开发中的应用技巧。

4. Django中间件与安全性

4.1 Django中间件工作原理

4.1.1 理解中间件概念与作用

中间件是Django框架中一个核心概念,它提供了一种机制,可以介入请求处理的各个阶段。在Django的请求/响应处理流程中,中间件位于Web服务器和你的Django视图之间。中间件可以处理每个请求和响应,执行代码如身份验证、维护会话、跟踪请求等。

具体地,中间件的主要作用包括:

  • 执行前请求处理,在请求到达视图之前执行一些预操作。
  • 执行后响应处理,当响应被发送到客户端后,执行一些后续的操作。
  • 请求全周期处理,可以追踪整个请求的处理过程。

一个典型的中间件实现包含以下结构:

class MyMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # 请求处理之前的代码
        response = self.get_response(request)
        # 响应处理之后的代码
        return response

使用中间件可以帮助我们:

  • 拦截请求和响应
  • 对请求和响应进行修改
  • 访问请求/响应对象中的头信息和内容
  • 短路请求,例如当用户未通过身份验证时拒绝请求
  • 记录请求

4.1.2 自定义中间件的开发实践

开发自定义中间件是一个很常见的需求,下面我们将通过一个简单的示例来展示如何实现一个中间件。

实现自定义中间件

假设我们想要开发一个中间件,用于记录每一个访问的IP地址,并记录访问时间。

import time

class LogIpAndTimeMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        current_time = time.strftime("%Y-%m-%d %H:%M:%S")
        ip_address = request.META.get('REMOTE_ADDR')
        with open('access_log.txt', 'a') as f:
            f.write(f"{current_time} - IP: {ip_address}\n")
        return response
注册中间件

确保在你的Django项目的 settings.py 文件中的 MIDDLEWARE 配置项中添加了自定义中间件的路径:

MIDDLEWARE = [
    ...
    'path.to.your.LogIpAndTimeMiddleware',
    ...
]
测试中间件

在测试中间件时,可以通过访问不同的URL来触发中间件记录日志,并检查 access_log.txt 文件中是否有新的日志条目。

问题排查

如果中间件未按预期工作,可以通过检查以下几点来排查问题:

  • 确认中间件是否被添加到 MIDDLEWARE 列表中,确保没有语法错误。
  • 检查请求和响应对象的处理逻辑是否正确。
  • 查看Django的日志文件获取错误信息。

4.2 Django安全机制与防护措施

4.2.1 Django安全框架概述

Django框架本身就包含了许多安全机制来帮助我们保护应用免遭常见的网络攻击。这些机制包括但不限于:

  • 使用CSRF令牌防御跨站请求伪造攻击。
  • 使用XSS过滤防御跨站脚本攻击。
  • 采用HTTPS传输加密敏感数据。
  • 增强数据库查询的安全性,防止SQL注入。
  • 强制执行安全密码策略。

4.2.2 防止常见攻击的策略和实施

CSRF防御

跨站请求伪造(CSRF)是一种常见且危险的攻击方式。Django通过在cookie中存储一个特定的令牌值,然后在每个POST请求中要求这个值,从而实现CSRF防御。

在Django中,通常不需要手动编写代码来处理CSRF令牌,因为Django表单和模板已经内置了这一功能。但是在需要手动创建表单的情况下,需要确保在表单中包含以下内容:

<form method="post">
    {% csrf_token %}
    ...
</form>
HTTPS实施

为了确保数据传输的安全性,应该尽可能地在你的Django应用中启用HTTPS。虽然这不仅仅是中间件的责任,但中间件可以用来强制重定向所有HTTP请求到HTTPS:

from django.http import HttpResponsePermanentRedirect

class HTTPSOnlyMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if not request.is_secure():
            return HttpResponsePermanentRedirect('***' + request.get_host() + request.get_full_path())
        response = self.get_response(request)
        return response

请记住,使用HTTPS需要一个有效的SSL证书,可以是自签名的,也可以是商业签名的证书。

总结

本文介绍了Django中间件的工作原理,包括中间件的概念、作用以及如何开发自定义中间件。接着讨论了Django安全机制,包括CSRF防御和HTTPS的实施。通过这些措施,可以大大提升Django项目的安全水平。

通过本章节的学习,你应该能够理解中间件在Django中的重要性,并能够为自己项目定制和优化中间件以满足特定需求。同时,你也应该对如何使用Django提供的安全机制来保护你的项目有了更深刻的认识。

5. Django REST框架与API开发

5.1 Django REST框架简介

5.1.1 REST框架的作用与优势

REST (Representational State Transfer) 架构风格是一种在分布式系统之间进行数据交换的设计哲学。Django REST framework(DRF)是一个强大的、灵活的工具包,用于构建Web API。它提供了一个可扩展的序列化器机制,用于将模型实例转换成JSON、XML或其他内容类型,同时也支持客户端对数据的创建、获取、更新和删除操作。

DRF的优势在于其简洁性和灵活性,它允许开发者能够快速地构建一个API,并且可以轻松地自定义,以满足各种业务需求。它还内置了一些辅助功能,比如权限控制、认证机制和节流,这些都能帮助开发者构建一个健壮且安全的API。

由于Django REST framework是建立在Django框架之上的,因此它继承了Django的MVC设计模式,这使得Django开发者能够更容易地过渡到Web API的开发。DRF还提供了一个Web浏览器控制台,允许开发者以一种直观的方式测试API,这大大提高了开发和调试的效率。

5.1.2 构建RESTful API的流程

构建RESTful API的过程涉及多个步骤,从规划API的资源结构开始,到实现具体的视图逻辑,再到测试API的响应。以下是构建RESTful API的基本流程:

  1. 需求分析与规划 :首先需要确定API将要支持的资源,以及各个资源之间的关系。例如,如果有一个博客系统,资源可能包括文章、评论和用户。

  2. 定义序列化器(Serializers) :序列化器用于将模型实例转换成JSON格式的数据,反之亦然。根据需求,定义序列化器并指定哪些字段需要被序列化或反序列化。

  3. 创建视图(Views) :视图负责处理用户的请求,并返回适当的响应。可以使用Django REST framework提供的视图类,如 APIView ListView DetailView 等来快速实现。

  4. 配置URL路由(URLs) :需要设置URLs以便能够将HTTP请求映射到对应的视图。DRF允许使用路由器(Routers)来自动生成API的URL配置。

  5. 编写权限与认证代码 :为了保护API的安全性,需要实现权限控制和认证机制。DRF提供了多种权限和认证方式,例如TokenAuthentication、SessionAuthentication等。

  6. 测试API :构建API后,使用DRF提供的测试客户端或其他API测试工具来验证API的功能性和正确性。

下面是一个简单的例子,展示了如何使用Django REST framework来构建一个简单的API视图:

from rest_framework import viewsets
from myapp.serializers import ArticleSerializer
from myapp.models import Article

class ArticleViewSet(viewsets.ModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

在这个例子中,我们创建了一个 ArticleViewSet 类,该类继承自 viewsets.ModelViewSet 。DRF会自动为我们提供获取文章列表、获取单个文章、创建文章、更新文章和删除文章等操作。

5.2 Django REST框架高级特性

5.2.1 视图集与路由器的使用

视图集(ViewSets)是Django REST framework中用于处理多个视图逻辑和关联的URL路由的类。 ModelViewSet 是视图集中最常用的类,它集成了标准的CRUD(创建、读取、更新、删除)操作。使用视图集可以大大简化代码,并使得代码更加清晰和易于管理。

路由器(Routers)则自动处理了URL的注册。通过向路由器注册视图集,我们可以创建标准的RESTful API路由结构。使用路由器还可以避免手动编写大量URL配置代码。

下面是如何使用路由器来注册 ArticleViewSet 的示例:

from rest_framework.routers import DefaultRouter
from myapp.views import ArticleViewSet

router = DefaultRouter()
router.register(r'articles', ArticleViewSet)

urlpatterns = router.urls

在这个例子中,我们创建了一个路由器实例,并注册了 ArticleViewSet 。路由器将自动为文章资源生成对应的URL模式。

5.2.2 权限控制与认证机制

为了保护API的安全性,Django REST framework提供了灵活的权限控制系统。权限可以基于视图来设置,也可以全局应用。DRF提供了多种内置的权限类,例如 IsAuthenticated IsAdminUser IsAuthenticatedOrReadOnly 等。

认证机制允许开发者验证用户身份,确保只有经过验证的用户才能访问受保护的API端点。DRF支持多种认证方式,包括基于会话的认证、基于令牌的认证、基本认证、摘要认证等。

下面是如何在Django REST framework中设置全局权限的示例:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    ]
}

在这个配置中,我们设置了默认的权限为所有API请求都需要经过身份验证,同时也设置了默认的认证方式为会话认证和令牌认证。这意味着所有API调用都必须携带有效的会话或令牌,否则将被拒绝访问。

以上只是Django REST framework中权限控制与认证机制的冰山一角。开发者可以通过扩展这些类或编写自定义的权限和认证类,来满足各种特定的安全需求。

6. Django项目实战与性能调优

在前几章节中,我们已经探讨了Django的架构、基础操作、模板系统、安全性等多个方面。现在,我们将结合实战案例来了解如何在项目中应用这些知识点,并进一步学习性能调优技巧。

6.1 Django项目实战案例分析

6.1.1 真实案例的项目搭建步骤

以一个博客系统为例,我们来分解一个Django项目的搭建步骤:

  1. 需求分析 :确定系统需要实现的用户注册登录、文章发布、评论、点赞等基本功能。
  2. 环境准备 :安装Python环境,创建虚拟环境,安装Django。
  3. 项目初始化 :通过 django-admin startproject 创建项目骨架。
  4. 配置项目 :设置数据库连接、中间件、静态文件路径等。
  5. 模型层设计 :使用Django ORM设计用户、文章、评论等模型。
  6. 视图与URL配置 :根据需求编写视图逻辑,配置URL路由。
  7. 模板设计 :使用Django模板系统,设计前端页面。
  8. 表单处理 :实现文章和评论的表单提交与验证。
  9. 中间件与安全设置 :添加自定义中间件,增加CSRF防护等。
  10. RESTful API开发 :使用Django REST framework,为前端提供数据接口。

6.1.2 项目中遇到的问题与解决方案

在项目开发过程中,可能会遇到如下问题:

  • 性能瓶颈 :特别是在用户量激增时,可能会出现性能瓶颈。解决方案可能包括数据库优化、缓存使用、负载均衡等。
  • 安全性问题 :比如XSS攻击、CSRF攻击等。通过中间件的使用和开发,以及遵循安全编码实践,可以有效防范这些攻击。
  • 功能迭代 :随着业务发展,功能需要不断迭代。可以利用Django的迁移系统平滑地进行数据模型的变更。

接下来,我们深入探讨性能调优的实战技巧。

6.2 Django性能优化技巧

6.2.1 性能测试与瓶颈分析

性能测试是确定系统瓶颈的重要步骤。可以使用工具如Apache JMeter或Django自带的测试框架进行压力测试。在测试中,特别关注数据库查询、视图渲染时间和API响应时间。

在分析瓶颈时,需要注意以下几点:

  • 数据库查询效率 :使用 django-debug-toolbar 插件查看SQL查询语句,优化慢查询。
  • 代码执行效率 :对于热点代码,使用 cProfile 进行性能分析。
  • 缓存使用情况 :确保热点数据使用缓存,减少数据库访问频率。

6.2.2 性能提升的实战技巧

以下是性能优化的几个实战技巧:

  • 数据库优化 :合理设计索引,使用数据库的查询优化器,以及选择合适的数据库引擎。
  • 缓存策略 :使用Django的缓存框架,如内存缓存(LocMemCache)、文件缓存(FileBasedCache)或分布式缓存(Redis、Memcached)。
  • 代码优化 :减少不必要的数据库查询,使用QuerySet API的 select_related prefetch_related 方法减少数据库访问。
  • 静态文件管理 :利用Django的静态文件框架,结合CDN提高文件加载速度。
  • 异步任务处理 :使用Celery等工具处理耗时任务,提高用户请求的响应速度。

在实战中,我们还需要结合具体的业务逻辑和资源情况,灵活运用上述技巧,以达到最佳的性能优化效果。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:本项目为Django Web框架的3.0版本中文文档,详尽介绍了Django的使用方法、API参考、最佳实践和常见问题解答。包含了构建信息、模块索引、目录结构、术语解释、全文搜索功能等关键文档部分。通过这些内容,开发者可以深入学习Django的安装、配置、模型、视图、模板、URL设置、表单、中间件、命令管理、数据库操作、缓存系统、性能优化、测试及部署等核心功能。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值