图书管理系统及django聚合查询、分组查询、F与Q查询

图书管理系统

图书管理系统基础环境准备

1.pycharm新建一个django项目
image
2.新建一个数据库用于存储项目所需数据

create database day07

image
3.配置pycharm基础环境配置
1)创建static目录
2)static目录拷贝静态资源目录
image
3)settings.py添加templates路径

TEMPLATES = [
DIRS': [os.path.join(BASE_DIR,'templates')]

4)settings.py添加static目录路径

STATICFILES_DIRS = [os.path.join(BASE_DIR,'static'),]

6)settings.py添加数据库支持

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'day07',
        'USER': 'root',
        'PASSWORD': 'Abcd1234',
        'HOST': '127.0.0.1',
        'PORT': 3306,
        'CHARSET': 'utf8',
    }
}

7)settings.py关闭csfr配置

MIDDLEWARE = [
 # 'django.middleware.csrf.CsrfViewMiddleware',

ps:如果不是通过pycharm创建应用,需要到settings.py注册手动新建的app

图书管理系统表设计及创建

1.表设计
创建4个表:Book、Publish、Author、Author_Detail。
表名:书籍表、出版社表、作者表和作者详情表。
先考虑表普通字段,在考虑外键设计
表普通字段:
Book:title、price、publish_time
Publish:name、address
Author:name、age
Author_Detail:phone、address
外键字段:
书籍表和出版社表关系推演:
书籍表:一本书是否可以有多个出版社:不可以
出版社:一个出版社是否可以出版多本书:可以
结论:一对多,外键建立在多的一方,即书籍表

书籍表和作者表关系推演:
书籍表:一本书是否可以有多个作者:可以
作者表:一个作者是否可以出版多本书:可以
结论:多对多,通过第三张表创建,ORM支持在任意一张创建外键字段自动创建第三张关系表

作者表和作者详情表关系推演:
作者表:每个作者是否可以有多个具体作者详情:不可以
作者详情表:每个详情是否可以包含多个作者:不可以
结论:一对一,建议外键字段建立在访问频率更高的表上,因此建议在作者表建立外键

models.py
class Book(models.Model):
    """图书表"""
    title = models.CharField(max_length=32,verbose_name='书名')
    price = models.DecimalField(max_digits=8,decimal_places=2,verbose_name='价格')
    publish_time = models.DateField(auto_now_add=True)

    # 书籍与出版社的一对多关系字段
    publish = models.ForeignKey(to='publish', on_delete=models.CASCADE)
    # 书籍与作者的多对多关系字段(自动创建第三张表)
    authors = models.ManyToManyField(to='Author')

    def __str__(self):
        return f'书籍对象:{self.title}'


class Publish(models.Model):
    """出版社表"""
    name=models.CharField(max_length=32,verbose_name='名称')
    address = models.CharField(max_length=64,verbose_name='地址')




class Author(models.Model):
    """作者表"""
    name = models.CharField(max_length=32,verbose_name='姓名')
    age = models.IntegerField(verbose_name='年龄')
    # 作者与作者详情的一对一关系
    author_detail = models.OneToOneField(to='AuthorDetail',on_delete=models.CASCADE)



class AuthorDetail(models.Model):
    """作者详情表"""
    phone = models.BigIntegerField(verbose_name='电话号码')
    address=models.CharField(max_length=64,verbose_name='家庭地址')

# 数据库迁移
打开pycharm终端命令行(Terminal):
D:\pythonProject\djangoday07>python38 manage.py makemigrations
D:\pythonProject\djangoday07>python38 manage.py migrate

# 手动录入数据
ps:先录入没有外键字段表,在录入外键字段表。

通过pycharm自带的数据库连接手动录入数据:
image
Book:
image
Publish:
image
Author:
image
AuthorDetail:
image
authors:
image

图书管理系统之首页展示

urls.py:
from BookManageSystem import views
# 首页展示(也可以考虑使用路由分发)
path('home/',views.home_func,name='home_view'),

views.py:
from django.shortcuts import render,redirect,HttpResponse,reverse
from BookManageSystem import models
def home_func(request):
    return render(request, 'homePage.html')

homePage.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
    {% load static %}
    <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.css' %}">
    <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.js' %}"></script>
</head>
<body>
    <nav class="navbar navbar-default">
                  <div class="container-fluid">
                    <!-- Brand and toggle get grouped for better mobile display -->
                    <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="#">BMS</a>
                    </div>

                    <!-- Collect the nav links, forms, and other content for toggling -->
                    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                      <ul class="nav navbar-nav">
                        <li class="active"><a href="#">图书 <span class="sr-only">(current)</span></a></li>
                        <li><a href="#">作者</a></li>
                        <li class="dropdown">
                          <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">更多 <span class="caret"></span></a>
                          <ul class="dropdown-menu">
                            <li><a href="#">Action</a></li>
                            <li><a href="#">Another action</a></li>
                            <li><a href="#">Something else here</a></li>
                            <li role="separator" class="divider"></li>
                            <li><a href="#">Separated link</a></li>
                            <li role="separator" class="divider"></li>
                            <li><a href="#">One more separated link</a></li>
                          </ul>
                        </li>
                      </ul>
                      <form class="navbar-form navbar-left">
                        <div class="form-group">
                          <input type="text" class="form-control" placeholder="书名">
                        </div>
                        <button type="submit" class="btn btn-default">查询</button>
                      </form>
                      <ul class="nav navbar-nav navbar-right">
                        <li><a href="#">jason</a></li>
                        <li class="dropdown">
                          <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">更多操作 <span class="caret"></span></a>
                          <ul class="dropdown-menu">
                            <li><a href="#">Action</a></li>
                            <li><a href="#">Another action</a></li>
                            <li><a href="#">Something else here</a></li>
                            <li role="separator" class="divider"></li>
                            <li><a href="#">Separated link</a></li>
                          </ul>
                        </li>
                      </ul>
                    </div><!-- /.navbar-collapse -->
                  </div><!-- /.container-fluid -->
                </nav>
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-2">
                <div class="list-group">
                  <a href="{% url 'home_view'%}" class="list-group-item active">
                    首页展示
                  </a>
                  <a href="#" class="list-group-item">图书列表</a>
                  <a href="#" class="list-group-item">出版社列表</a>
                  <a href="#" class="list-group-item">作者列表</a>
                  <a href="#" class="list-group-item">更多详情</a>
                </div>
                <div class="list-group">
                  <a href="#" class="list-group-item active">
                    首页展示
                  </a>
                  <a href="#" class="list-group-item">图书列表</a>
                  <a href="#" class="list-group-item">出版社列表</a>
                  <a href="#" class="list-group-item">作者列表</a>
                  <a href="#" class="list-group-item">更多详情</a>
                </div>
                <div class="list-group">
                  <a href="#" class="list-group-item active">
                    首页展示
                  </a>
                  <a href="#" class="list-group-item">图书列表</a>
                  <a href="#" class="list-group-item">出版社列表</a>
                  <a href="#" class="list-group-item">作者列表</a>
                  <a href="#" class="list-group-item">更多详情</a>
                </div>

            </div>
            <div class="col-md-10">
                   <div class="panel panel-primary">
                      <div class="panel-heading">
                        <h3 class="panel-title">BMS</h3>
                      </div>
                      <div class="panel-body">
                        <div class="page-header">
                          <h1>图书管理系统 <small>更多经常等你来玩</small></h1>
                        </div>
                          <div class="jumbotron">
                          <h1>全球最大的图书网址!</h1>
                          <p>友情链接</p>
                          <p><a class="btn btn-primary btn-lg" href="#" role="button">点击精彩</a></p>
                        </div>

                      </div>
                    </div>
                    <div class="row">
                    <div class="col-xs-6 col-md-3">
                <a href="#" class="thumbnail">
                  <img src="https://img0.baidu.com/it/u=2693313206,3402454070&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750" alt="...">
                </a>
              </div>
                    <div class="col-xs-6 col-md-3">
                <a href="#" class="thumbnail">
                  <img src="https://img0.baidu.com/it/u=2693313206,3402454070&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750" alt="...">
                </a>
              </div>
                    <div class="col-xs-6 col-md-3">
                <a href="#" class="thumbnail">
                  <img src="https://img0.baidu.com/it/u=2693313206,3402454070&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750" alt="...">
                </a>
              </div>
                    <div class="col-xs-6 col-md-3">
                <a href="#" class="thumbnail">
                  <img src="https://img0.baidu.com/it/u=2693313206,3402454070&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750" alt="...">
                </a>
              </div>
            </div>

            </div>
        </div>
    </div>
</body>
</html>
首页布局:
1.先弄个导航条的可访问性,就是导航条带连接跳转的,编辑里面相关数据。
2.弄个容器布局,要全部占满页面的,container-fluid(div3.在容器里面弄个row(div),方便后面分12格.
4.弄两个col-md-2,col-md-10.
5.col-md-2(div)里面弄个列表组,弄成36.col-md-10(div),添加面板,在面板里增加页头和巨幕,最后放4张缩略图。

image

图书管理系统之书籍展示

urls.py:
# 图书列表展示页
path('book_list/',views.book_list_func, name='book_list_view'),

views.py:
def book_list_func(request):
    # 1.获取所有的图书数据
    book_queryset = models.Book.objects.all()  # queryset[数据对象,数据对象...]
    # 2.返回html页面并在页面上展示图书数据
    return render(request,'bookListPage.html',locals())
    # locals() 指获取book_queryset对象并把该变量传递给bookListPage.html页面,方便html展示数据

homePage.html:
2.在<div class="col-md-10">下面添加模板,用于后面其它页面继承添加想要修改的内容
{% block  content %}
把原来容器10格里面的内容全部粘贴进来
{% endblock %}
1.首页展示栏左侧修改图书列表链接跳转:
<a href="{% url 'book_list_view' %}" class="list-group-item">图书列表</a>


3.bookListPage.html:
{%  extends 'homePage.html' %}

{% block content %}
    <h2 class="text-center">图书展示页</h2>
    <table class="table table-striped table-hover">
        <thead>
            <tr>
                <th>编号</th>
                <th>书名</th>
                <th>价格</th>
                <th>日期</th>
                <th>出版社</th>
                <th>作者</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            {% for book_obj in book_queryset %}   <!--book_queryset=[数据对象,数据对象,数据对象]-->
                <tr>
                    <td>{{ forloop.counter }}</td>   <!--可以展示主键值 也可以展示从1开始的有序数列-->
                    <td>{{ book_obj.title }}</td>
                    <td>{{ book_obj.price }}</td>
                    <td>{{ book_obj.publish_time|date:'Y-m-d' }}</td>
                    <td>{{ book_obj.publish.name }}</td>
                    <td>{% for author_obj in book_obj.authors.all %}  <!--queryset [作者对象,作者对象]-->
                            {% if forloop.last %}
                                {{ author_obj.name }}
                                {% else %}
                                    {{ author_obj.name }},
                            {% endif %}
                    {% endfor %}
                    </td>
                    <td>
                        <a href="#" class="btn btn-primary btn-xs">编辑</a>
                        <a href="#" class="btn btn-danger btn-xs">删除</a>
                    </td>
                    <td></td>
                </tr>
            {% endfor %}

        </tbody>
    </table>
{#分页功能#}
    <nav aria-label="Page navigation" class="text-center">
  <ul class="pagination ">
    <li>
      <a href="#" aria-label="Previous">
        <span aria-hidden="true">&laquo;</span>
      </a>
    </li>
    <li><a href="#">1</a></li>
    <li><a href="#">2</a></li>
    <li><a href="#">3</a></li>
    <li><a href="#">4</a></li>
    <li><a href="#">5</a></li>
    <li>
      <a href="#" aria-label="Next">
        <span aria-hidden="true">&raquo;</span>
      </a>
    </li>
  </ul>
</nav>
{% endblock %}

image

图书管理系统之书籍添加

urls.py:
# 图书数据添加页
path('book_add/',views.book_add_func,name='book_add_view'),

views.py:
def book_add_func(request):
    if request.method == 'POST':
        title = request.POST.get('title')  # 列表最后一个数据值
        price = request.POST.get('price')  # 列表最后一个数据值
        publish_time = request.POST.get('publish_time')  # 列表最后一个数据值
        publish_id = request.POST.get('publish_id')  # 列表最后一个数据值
        author_id_list = request.POST.getlist('author_id_list') # 获取完整的列表数据
        # TODO:一些小判断自己完成
        book_obj = models.Book.objects.create(title=title,price=price,publish_time=publish_time,
                                              publish_id=publish_id)
        book_obj.authors.add(*author_id_list)  # add(1,2,3)
		#书籍添加和用户有关系,所以需要操作第三张表添加书籍对应的作者,这句话表示通过当前书籍对象到第三张表authors,给这个书籍对象添加作者ID为author_id_list里面的所有ID
        # 重定向到书籍展示页
        return redirect('book_list_view')  # 只支持没有动态匹配的别名反向解析
    #2. 分析可得页面需要出版社和作者的全部数据
    publish_queryset = models.Publish.objects.all()
    author_queryset = models.Author.objects.all()
    # 1.返回一个可以让用户输入书籍相关数据的html页面
    return render(request,'bookAddPage.html',locals())

homeListPage.html:
添加图书添加按钮
<a href="{% url 'book_add_view' %}" class="btn btn-success">图书添加</a>

bookAddPage.html:
{% extends 'homePage.html' %}

{% block content %}
    <h2 class="text-center">图书添加页</h2>
    <form action="" method="post">
        <p>title:
            <input type="text" name="title" class="form-control">
        </p>
         <p>price:
            <input type="text" name="price" class="form-control">
        </p>
         <p>publish_time:
            <input type="date" name="publish_time" class="form-control">
        </p>
         <p>publish_name:
                <!--展示系统中已有的出版社信息供选择 -->
             <select name="publish_id" id="" class="form-control">
                 {% for publish_obj in publish_queryset %}  <!--queryset [数据对象,数据对象] --> pk表示表的主键
                     <option value="{{ publish_obj.pk }}">{{ publish_obj.name }}</option>
                 {% endfor %}

             </select>
        </p>
         <p>author_list:
            <!--展示系统中已有的作者信息供选择 -->
             <select name="author_id_list" id="" multiple class="form-control">
                 {% for author_obj in author_queryset %} <!--queryset [数据对象 数据对象] -->
                     <option value="{{ author_obj.pk }}">{{ author_obj.name }}</option>
                 {% endfor %}

             </select>
        </p>

        <input type="submit" value="书籍添加" class="btn btn-block btn-success">
    </form>
{% endblock %}

image
image

图书管理系统书籍编辑

urls.py:
# 图书数据编辑页
path('book_edit/<int:book_pk>/',views.book_edit_func,name='book_edit_view'), # book_edit_func(request对象,book_pk=’‘)
#为啥加<int:book_pk>动态解析,因为后端要获取用户编辑具体某项数据的ID值,所以加上方便后台和前端页面做数据处理

views.py
def book_edit_func(request,book_pk):
    # 1.根据匹配到的数据主键值查询数据对象
    edit_obj = models.Book.objects.filter(pk=book_pk).first()
    if request.method == 'POST':
        title = request.POST.get('title')  # 列表最后一个数据值
        price = request.POST.get('price')  # 列表最后一个数据值
        publish_time = request.POST.get('publish_time')  # 列表最后一个数据值
        publish_id = request.POST.get('publish_id')  # 列表最后一个数据值
        author_id_list = request.POST.getlist('author_id_list')  # 获取完整的列表数据
                          		   models.Book.objects.filter(pk=book_pk).update(title=title,price=price,publish_time=publish_time,
publish_id=publish_id)
        edit_obj.authors.set(author_id_list)
		#同步多对多第三张表数据,给书籍对象更新对应作者,set(必须放元组或者列表)
        return redirect('book_list_view')
    #3.根据分析可得也需要所有出版社和作者的信息
    publish_queryset = models.Publish.objects.all()
    author_queryset = models.Author.objects.all()
    # 2. 传递给html页面并展示给用户看
    return render(request,'bookEditPage.html',locals())

bookListPage.html:
<a href="{% url 'book_edit_view' book_obj.pk %}" class="btn btn-primary btn-xs">编辑</a>

bookEditPage.html:
{% extends 'homePage.html' %}

{% block content %}
    <h2 class="text-center">图书编辑页</h2>
    <form action="" method="post">
        <p>title:
            <input type="text" name="title" class="form-control" value="{{ edit_obj.title }}">
        </p>
         <p>price:
            <input type="text" name="price" class="form-control" value="{{ edit_obj.price }}">
        </p>
         <p>publish_time:
            <input type="date" name="publish_time" class="form-control" value="{{ edit_obj.publish_time|date:'Y-m-d' }}">
        </p>
         <p>publish_name:
                <!--展示系统中已有的出版社信息供选择 -->
             <select name="publish_id" id="" class="form-control">
                 {% for publish_obj in publish_queryset %}  <!--queryset [数据对象,数据对象] -->
                     <!--根据待编辑的书籍对象查询对应的出版社 与系统所有的出版社比对 如果相同则添加默认选中的属性 selected  -->
                     {% if edit_obj.publish == publish_obj %}
                        <option value="{{ publish_obj.pk }}" selected>{{ publish_obj.name }}</option>
                     {% else %}
                         <option value="{{ publish_obj.pk }}">{{ publish_obj.name }}</option>
                     {% endif %}

                 {% endfor %}

             </select>
        </p>
         <p>author_list:
            <!--展示系统中已有的作者信息供选择 -->
             <select name="author_id_list" id="" multiple class="form-control">
                 {% for author_obj in author_queryset %} <!--queryset [数据对象 数据对象] -->
                     <!--成员运算判断循环的作者对应是否在待编辑的书籍作者对象列表中 -->
                     {% if author_obj in edit_obj.authors.all %}
                         <option value="{{ author_obj.pk }}" selected>{{ author_obj.name }}</option>
                     {% else %}
                         <option value="{{ author_obj.pk }}">{{ author_obj.name }}</option>
                     {% endif %}
                 {% endfor %}

             </select>
        </p>

        <input type="submit" value="书籍编辑" class="btn btn-block btn-success">
    </form>
{% endblock %}

图书管理系统书籍删除

urls.py:
# 图书数据删除接口
path('book_delete/<int:book_pk>/', views.book_delete_func, name='book_delete_view'),

views.py:
def book_delete_func(request, book_pk):
    # 删除书籍与作者的绑定关系
    delete_book_obj = models.Book.objects.filter(pk=book_pk).first()
    delete_book_obj.authors.clear()
    # 删除书籍数据
    models.Book.objects.filter(pk=book_pk).delete()
    return redirect('book_list_view')

bookListPage.html:
<a href="{% url 'book_delete_view' book_obj.pk %}" class="btn btn-danger btn-xs delBtn">删除</a>

{% block jss %}
    <script>
        $('.delBtn').click(function (){
            let isDel = confirm('你确定要删除吗')
            if (!isDel){
                return false
            }
        })
    </script>
{% endblock %}

聚合查询

聚合函数:Max Min Sum Count Avg
在ORM中支持单独使用聚合函数  aggregate

def main():
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoday07.settings')
    import django
    django.setup()
    from BookManageSystem import models
    # 聚合函数需要导入模块才可以使用
    from django.db.models import Max,Min,Sum,Count,Avg
    res = models.Book.objects.aggregate(Max('price'),Count('pk'),最小价格=Min('price'),allPrice=Sum('price'),平均价格=Avg('price'))
    print(res)

main()

分组查询

"""
如果执行orm分组查询报错 并且由关键字sql_mode strict mode
解决:移除sql_mode中的only_full_group_by
"""
# 分组查询(重要)
    # 统计每一本书的作者个数
    res = models.Book.objects.annotate(author_num=Count('authors__pk')).values('title','author_num')
    print(res)
    # 统计每个出版社卖的最便宜的书的价格
    res=models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price')
    print(res)
    # 统计不止一个作者的图书
    # 1.先统计每本书的作者个数
    res = models.Book.objects.annotate(author_num=Count('authors__pk'))
    # 2.筛选出作者个数大于1的数据
    res = models.Book.objects.annotate(author_num=Count('authors__pk')).filter(author_num__gt=1).values('title','author_num')
    print(res)
    # 查询每个作者出的书的总价格
    res = models.Author.objects.annotate(sum_price=Sum('book__price'),count_book=Count('book__pk')).values('name','sum_price','count_book')
    print(res)
    """
    models.表名.objects.annotate()                             按照表分组
    models.表名.objects.values('字段名').annotate()             按照values括号内指定的字段分组 
    """
    # 查询书籍里面各出版社出版了总计多少书
    res = models.Book.objects.values('publish_id').annotate(count_pk=Count('pk')).values('publish_id','count_pk')
    print(res)

F与Q查询

1.现在Book表里面添加两个字段并发送数据库迁移命令
'''后续添加两个字段'''
    kucun = models.IntegerField(verbose_name='库存数',default=1000)  # 设置默认值
    maichu = models.IntegerField(verbose_name='卖出数',null=True)  # 允许为空
打开pycharm终端:python38 manage.py makemigrations 
python38 manage.py migrate

# 1.查询库存数大于卖出数的书籍
    '''查询条件不是明确的 也需要从数据库中获取 就需要使用F查询
      F:获取表中指定字段对应的数据作为查询条件    
'''
    from django.db.models import F
    res = models.Book.objects.filter(kucun__gt=F('maichu'))
    print(res)
    # 2.将所有书的价格涨800块(了解)
    models.Book.objects.update(price=F('price') + 800)
    # 3.将所有书的名称后面追加新款(了解)
    from django.db.models.functions import Concat
    from django.db.models import Value
    models.Book.objects.update(title=Concat(F('title'),Value('新款')))
    # 查询主键是1或者价格大于1500的书籍
     '''Q:可以将多个查询条件的关系做修改'''
    res = models.Book.objects.filter(pk=1,price__gt=1500)  # 逗号默认是and关系,所以查不出来
    from django.db.models import Q
    res = models.Book.objects.filter(Q(pk=1),Q(price__gt=1500)) # 逗号是and关系
    res = models.Book.objects.filter(Q(pk=1)|Q(price__gt=1500))  # !是or关系
    res = models.Book.objects.filter(~Q(pk=1)|Q(price__gt=1500)) #~取其中一个条件反,获取主键不是1的或者是价格大于1500的
    print(res)
    print(res.query)
#Q查询进阶操作
	q_obj= Q() #1.产生q对象
    q_obj.connector='or' # 默认多个条件的连接是and,可以修改为or
    q_obj.children.append(('pk',1)) # 添加查询条件
    q_obj.children.append(('price__gt',200)) #支持添加多个
    res = models.Book.objects.filter(q_obj) #查询支持直接写q对象
    for book in res:
        print(book.title)

book书籍手动录入一点数据:
image

posted @   悠悠-winter  阅读(149)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示