asp.net编程网页弹窗显示变量_许昌鲤鱼IT编程教育带你用Python开发企业门户网站(前端+后端)...

人生苦短,为什么我要用python?

  • 首先让我们来看一个2019年最新的编程语言权威排行榜github octoverse
  • 既然python如此流行,谁能告诉我why?易上手跨平台高薪水应用广TIPpython除了不能生孩子,啥都能干,如WEB开发,网络爬虫,数据分析,大数据,人工智能,服务器运维,自动化测试...

#实战目标

使用Python3.7+Django2.2+sqlite实现一个企业门户网站先睹为快

TIP

该网站能满足大多数企业门户网站的需求

#学习前提

  • 对编程感兴趣
  • 了解python的基础语法
  • 了解html/css/js

#环境搭建

#编程语言python3.7

  • windows环境下载安装包执行下载的安装包,注意在安装时选中Add Python 3.7 to PATH
57e994dd911fec89b2c59a1d1fb686fb.png
0452a76bc137a503e1da9aba0e109b9e.png

Mac环境

  • 下载安装文件
  • 执行下载的安装包
  • 配置

在~/.bash_profile 文件中添加如下配置

8b8e16a34513b1aee1c70fe1cdf14631.png

IDE pycharm专业版

  • windows环境下载pycharm Professional 安装包
f39d9b552612227531d771d04aa7e687.png
758a93f2df1635c06c7903882af219a7.png
278ff7ec13d9bf8b924c9c495bb4a00e.png
ee052676d21282c201313fe71261f9d4.png
d1a5b189db160e2ecc30c3fff50f5008.png
Mac环境下载pycharm Professional 安装包

#虚拟环境 virtualenvwrapper

虚拟环境的主要作用是给不同的项目创建独立的运行环境,每一个虚拟环境可以有自己版本的依赖包

  • Windows 安装在命令行执行
e4dd9fa4b58228ef6a63cc8a053dac3b.png

新建WORKON_HOME系统变量,值为一个有效的路径,用了存放虚拟环境

c88b1adac43b9de52db26867b2330992.png
c81837cad7f6dd925c6eaf8d12e52fd3.png
61c453115a84e06f8b0c310f5f48c2b2.png
be7d98b89b501ee96b70e97d3efc1c3a.png

TIP

打开控制面板-系统和安全-系统-高级系统设置-环境变量-系统变量-点击新建

  • 双击python的安装路径Scriptsvirtualenvwrapper.bat文件
bd57363bc01be4188329858efafc69aa.png

以管理员身份重新打开命令行

0c7b039313765baeeb69a551ec41ac75.png

Mac 安装

  • 在终端执行以下命令
1f4c10a041f1bde4fb5667e1191a7613.png

使用

a332fce524f126d156713da1842a6da5.png

初始化项目

#创建项目的虚拟环境

bb427485fa5cdff3a38580b766106df7.png

用pycharm新建django项目

  • 在新建面板的左侧选择django项目
  • 在Location中指定项目所在的位置
  • 在Existing interpreter 中指定项目的python解释器在Virtualenv Environment中的Interpreter 中选择创建的虚拟环境python所在的路径TIP一般Windows用的这个路径为 虚拟环境存放目录虚拟环境名称Scriptspython.exe一般Mac用户的这个路径为 用户名/.virtualenvs/虚拟环境名称/bin/python
  • 选中Enable Django admin
f43e854420a93821fd18fbd60d09b29f.png
打开 Run->Run 'project' 运行项目来测试django是否安装成功django 参考文档: Djano 官网 Djano 中文文档

#完善项目目录结构

  • 在项目目录下新建media文件夹用来存放上传资源
  • 在项目目录下新建static文件夹用来存放静态资源
  • 在项目目录下新建apps包用来存放应用

#pycharm 创建django应用

  • 打开 Tools->Run manage.py task
  • 在终端执行
037d29def581294e21df80040eb66b73.png

django项目目录结构解析

f9b12ef6deed258371917148b983e0b7.png

WEB原理解析和MVC介绍

#WEB原理解析

16e1f2c0bcfd1892676376b7878453ca.png
客户端用户发送请求服务器解析请求,计算数据并返回给客户端客户端解析返回的数据

#MVC介绍

29ec92729618e3ecfb26e170c694e1d1.png
客户端用户发送请求模型框架负责路由解析,根据路由寻找对应的控制器(Controller)和行为(action)行为(action)调用相关的模型(Model)进行数据操作行为(action)根据数据操作的结果调用视图(View)进行页面的渲染,输出到客户端

#静态页面路由配置

#添加View类

在apps.basic.views添加处理路由的View

2db19bfa20fae21f79c80fd932cdfd48.png

TIP

Django中view分为CBV(class base view)和FBV(function base view),推荐CBV

#添加html页面

在templates文件夹新新建一个index.html静态页面

#配置路由

在urls.py文件中添加

72cc7b38bff0f1b98a701f96f34881f0.png

静态资源处理

#在html页面中使用静态资源

copy前端准备好的模版文件(html)到templates文件夹中

#添加静态资源

copy前端准备好的静态资源文(css,js,image)件到static文件中

#配置静态文件查找路径配置

在settings.py中添加如下配置

a963b9c4d3d1804fa13e0ac1ccbfe5c1.png

模版的使用

#定义模版

58ea85db2b98aa2a9ca5bb431d73b2c5.png

配置其他路由和跳转

#View类

8655eb9b0c14ba1415b4aa215bd8a681.png

配置路由

3a703c7c2179d7072ac1eb368219afb9.png

TIP

注意detail路由的配置是为了传递参数到view中

#配置跳转

  • 直接跳转
f542b9cd772c74760826946e63fe71a5.png

记录导航选中状态

  • 在view中传递当前页面标识到模版
8a9ca031c1f18dcf4095ebc84b535467.png

在模版中根据标识设置class

首页产品动态关于

#模型定义

安装Pillow

由于模型中需要定以图片的上传,所以需要安装

pip install Pillow -i https://mirrors.aliyun.com/pypi/simple/ 

定义共同父类

from datetime import datetimefrom django.db import models# 定义共同类class BaseModel(models.Model): add_time = models.DateTimeField(verbose_name="添加时间",default=datetime.now) class Meta: abstract = True #不生成表

定义站点配置模型

class Config(BaseModel): name = models.CharField(verbose_name="站点名称", max_length=100) logo = models.ImageField(verbose_name="站点logo", max_length=300, upload_to="config/logo/%Y/%m") url = models.CharField(verbose_name="站点连接", max_length=100) wx_qr_code = models.ImageField(verbose_name="微信二维码",max_length=300,upload_to="config/wx/%Y/%m") tel = models.CharField(verbose_name="联系电话",max_length=20) hours = models.CharField(verbose_name="营业时间", max_length=40) mail = models.CharField(verbose_name="电子邮件", max_length=300) icp = models.CharField(verbose_name="备案号", max_length=50) class Meta: verbose_name = "站点配置" verbose_name_plural = verbose_name def __str__(self): return self.name

数据库表操作和创建管理员

  • 打开Tools->Run manage.py task
  • 生成表迁移
makemigrations
  • 将表迁移同步到数据库
migrate
  • 创建超级用户
createsuperuser

后台管理配置

#注册模型

在应用的admin.py文件中

#admin.pyfrom django.contrib import adminfrom apps.basic.models import Configclass ConfigAdmin(admin.ModelAdmin): passadmin.site.register(Config,ConfigAdmin)

#配置中文和时区

在settings.py中配置中文和时区

#settings.pyLANGUAGE_CODE = 'zh-hans'TIME_ZONE = 'Asia/Shanghai'USE_TZ = False

#修改网页title和站点header

在应用的admin.py文件中

#admin.py#修改网页title和站点headeradmin.site.site_title = "PyCMS后台管理"admin.site.site_header = "PyCMS"

#修改应用的中文名称

在应用的apps.py文件中修改应用的中文名称

#apps.pyclass BasicConfig(AppConfig): name = 'apps.basic' verbose_name = "站点基本"

#配置上传资源路径

在settings.py中配置上传资源路径

#settings.pyMEDIA_URL = "/media/"MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

#自定义表单

在应用的admin.py文件中,在管理器类中添加 fields 属性来定义表单要显示的字段

#admin.pyfrom django.contrib import adminfrom apps.basic.models import Configclass ConfigAdmin(admin.ModelAdmin): fields = ('name','logo','url','wx_qr_code','tel','hours','mail','icp')# Register your models here.admin.site.register(Config,ConfigAdmin)

#列表显示

在应用的admin.py文件中,在管理器类中添加 list_display 属性来定义列表要显示的字段

#admin.pyfrom django.contrib import adminfrom apps.basic.models import Configclass ConfigAdmin(admin.ModelAdmin): fields = ('name','logo','url','wx_qr_code','tel','hours','mail','icp') list_display = ('name','url','tel','hours','mail','icp')# Register your models here.admin.site.register(Config,ConfigAdmin)

admin登陆添加验证码

  • 安装依赖
pip3 install django-multi-captcha-adminpip3 install django-simple-captcha
  • 配置
#settings.pyINSTALLED_APPS = [ 'multi_captcha_admin',#需要在django.contrib.admin前添加 .... 'captcha',#验证码模块]MULTI_CAPTCHA_ADMIN = { 'engine': 'simple-captcha',}
  • 添加路由
#urls.pyfrom django.urls import path, include...url(r'^captcha/', include('captcha.urls')),
  • 数据迁移
migrate

#分配数据到模版展示

#获取和分配数据(objects.get()获取一条)

# views.pyfrom apps.basic.models import Configclass IndexView(View): def get(self, request, *args, **kwargs): # 获取一条数据对象 config = Config.objects.get() return render(request, 'index.html',{ 'currentPage':'index', 'config':config #将对象分配到模版 })

#展示数据

  • 普通数据展示

{{ config.tel }}({{ config.hours }})

  • 上传图片数据展示模版中使用
    在urls.py中配置上传文件请求路由# urls.py from django.views.static import serve from project.settings import MEDIA_ROOT urlpatterns = [ ... # 上传文件访问的路由配置 url(r'^media/(?P.*)$', serve, {"document_root": MEDIA_ROOT}), ]

友情连接

#模型定义

class Link(BaseModel): name = models.CharField(verbose_name="友情连接名称", max_length=100) url = models.CharField(verbose_name="友情连接地址", max_length=300) class Meta: verbose_name = "友情连接" verbose_name_plural = verbose_name def __str__(self): return self.name

TIP

模型注册,表迁移,数据同步参考站点配置模型

#获取和分配数据(objects.all()获取所有)

#views.pyclass IndexView(View): def get(self, request, *args, **kwargs): # 获取一条数据对象 config = Config.objects.get() # 获取友情链接 links = Link.objects.all() return render(request, 'index.html',{ 'currentPage':'index', 'config':config, #将对象分配到模版 'links':links })

#展示数据

{% for link in links %}{{ link.name }}{% endfor %}

TIP

Link.objects.all()返回的是一个QuerySet,需要在模版中通过for in来遍历得到每一对象

#首页轮播图

#模型定义

class Carousel(BaseModel): title = models.CharField(verbose_name="轮播图名称", max_length=100) image = models.ImageField(verbose_name="轮播图图片", max_length=300, upload_to="carousel/%Y/%m") desc = models.CharField(verbose_name="轮播图描述", max_length=100) class Meta: verbose_name = "首页轮播图" verbose_name_plural = verbose_name def __str__(self): return self.title

TIP

模型注册,表迁移,数据同步,获取和分配数数据,展示数据 参考友情链接模型

#产品

#模型定义

class Product(BaseModel): name = models.CharField(verbose_name="产品名称", max_length=100) desc = models.TextField(verbose_name="产品描述", max_length=300) icon = models.ImageField(verbose_name="产品图标", max_length=300, upload_to="product/icon/%Y/%m") url = models.CharField(verbose_name="产品连接", max_length=100) image = models.ImageField(verbose_name="产品封面",max_length=300,upload_to="product/post/%Y/%m") is_show_index = models.BooleanField(verbose_name="是否显示在首页",default=False) class Meta: verbose_name = "产品" verbose_name_plural = verbose_name def __str__(self): return self.name

#数据获取(filter筛选)

#views.py# 获取首页需要的产品products = Product.objects.filter(is_show_index=True)

TIP

  • 模型注册,表迁移,数据同步,分配数数据,展示数据 参考友情链接模型
  • 数据获取使用filter进行筛选,filter返回结果也是一个QuerySet,在模版中需要用for in

#服务

#模型定义

# 服务class Service(BaseModel): name = models.CharField(verbose_name="服务名称", max_length=100) desc = models.TextField(verbose_name="服务描述", max_length=300) image = models.ImageField(verbose_name="服务封面",max_length=300,upload_to="service/post/%Y/%m") class Meta: verbose_name = "服务" verbose_name_plural = verbose_name def __str__(self): return self.name

TIP

模型注册,表迁移,数据同步,获取和分配数数据,展示数据 参考友情链接模型

#产品页面开发

TIP

参考首页开发

#动态页面开发

#动态模型

class News(BaseModel): name = models.CharField(verbose_name="动态标题", max_length=100) desc = models.TextField(verbose_name="动态描述", max_length=300) intro = models.TextField(verbose_name="动态简介", max_length=300) content = models.TextField(verbose_name="动态内容", max_length=300) read_nums = models.IntegerField(verbose_name="阅读人数", default=0) post = models.ImageField(verbose_name="封面图片",max_length=300,upload_to="news/post/%Y/%m") image = models.ImageField(verbose_name="详情图片", max_length=300, upload_to="news/detail/%Y/%m") class Meta: verbose_name = "动态" verbose_name_plural = verbose_name def __str__(self): return self.name

#安装分页应用

  • 参考 django-pure-pagination
  • 在虚拟环境中安装
pip3 install django-pure-pagination
  • 在settings.py中INSTALLED_APPS配置
#settings.pyINSTALLED_APPS = [ ... 'pure_pagination',#分页配置]
  • 在settings.py中配置分页参数
#settings.py# 分页相关配置PAGINATION_SETTINGS = { 'PAGE_RANGE_DISPLAYED': 6, 'MARGIN_PAGES_DISPLAYED': 2, 'SHOW_FIRST_PAGE_WHEN_INVALID': True,}

#在views.py中使用分页应用

from pure_pagination import Paginator, EmptyPage, PageNotAnIntegerclass NewsView(View): def get(self, request, *args, **kwargs): # 获取一条数据对象 config = Config.objects.get() # 获取友情链接 links = Link.objects.all() # 按添加时间倒序获取所有的动态 all_news = News.objects.order_by("-add_time") try: page = request.GET.get('page', 1) except PageNotAnInteger: page = 1 p = Paginator(all_news, per_page=2, request=request) news = p.page(page) return render(request, 'news.html',{ 'currentPage': 'news', 'config': config, 'links': links, 'news':news })

TIP

  • objects.order_by()是排序
  • 以上代码生成的news是一个分页对象

#在模版中使用分页

  • 动态遍历
 {% for item in news.object_list %} 
{{ item.name }}

{{ item.desc }}[详细]

阅读 {{ item.read_nums }} 发布时间:{{ item.add_time }}

{% endfor %}

TIP

分页对象需要遍历对象上的object_list

  • 分页器渲染
 
{% if news.has_previous %} 上一页 {% endif %} {% for page in news.pages %} {% if page %} {% ifequal page news.number %} {{ page }} {% else %} {{ page }} {% endifequal %} {% else %} ... {% endif %} {% endfor %} {% if news.has_next %} 下一页 {% endif %}

#动态详情页面开发

#获取动态并分配给模版

class NewsDetailView(View): def get(self, request,news_id, *args, **kwargs): # 获取一条数据对象 config = Config.objects.get() # 获取友情链接 links = Link.objects.all() # 获取动态 news = News.objects.get(id=int(news_id)) # 修改动态的阅读人数 news.read_nums += 1 news.save()  return render(request, 'newsDetail.html',{ 'currentPage': 'news', 'config': config, 'links': links, 'news':news })

TIP

  • objects.get(id=int(news_id))是根据id获取数据
  • 模版数据展示参考之前模型

#关于我们页面开发

#定义模型

# 公司简介class Intro(BaseModel): content = models.TextField(verbose_name="简介内容", max_length=300) image = models.ImageField(verbose_name="简介图片", max_length=300, upload_to="intro/%Y/%m") class Meta: verbose_name = "公司简介" verbose_name_plural = verbose_name def __str__(self): return self.content# 发展历程class Timeline(BaseModel): label = models.CharField(verbose_name="历程标签", max_length=100) desc = models.TextField(verbose_name="历程描述", max_length=100) image = models.ImageField(verbose_name="历程图片", max_length=300, upload_to="timeline/%Y/%m") class Meta: verbose_name = "发展历程" verbose_name_plural = verbose_name def __str__(self): return self.label

TIP

模型注册,表迁移,数据同步,获取和分配数数据, 参考友情链接模型

#数据展示

{% for intro in intros %} {% if forloop.counter|divisibleby:2 %} 

{{ intro.content }}

{{ intro.content }}

{% else %}

{{ intro.content }}

{% endif %}{% endfor %}

TIP

  • 在模版中遍历时可以用{% if forloop.counter|divisibleby:2 %}来判断当前是否是偶数
  • 成长历程的遍历同理

#配置错误页面

#准备相关的错误页面

  • 404.html

#修改settings.py文件

# 开发环境配置# DEBUG = True# ALLOWED_HOSTS = []# 线上环境配置DEBUG = FalseALLOWED_HOSTS = ['*']# 开发环境配置,静态文件查找路径配置# STATICFILES_DIRS = [# os.path.join(BASE_DIR, 'static'),# ]# 线上环境配置STATIC_ROOT = os.path.join(BASE_DIR, 'static')

#修改urls.py文件

from project.settings import STATIC_ROOTurlpatterns = [ ... # 静态资源访问的路由配置(线上配置only) url(r'^static/(?P.*)$', serve, {"document_root": STATIC_ROOT}),]

#收集项目所需依赖文件

pip3 freeze > requirements.txt

#部署上线

#购买云服务器(以阿里云为例)

  • 购买时操作系统选择CentOS 7.7 64位
  • 记录远程连接密码,在远程连接时用
  • 重置实例密码,该密码是登陆系统时使用

#开放云服务器的端口

在云服务器对应的实例中安全组规则中添加

允许自定义 TCP80/80 IPv4地址段访问0.0.0.0/0 允许自定义 TCP8000/8000IPv4地址段访问0.0.0.0/0 

#登陆服务器

  • 方法一:远程连接后登陆系统,用户名:root 密码:重置的实例密码
  • 方法二(推荐):在本机终端通过 ssh root@服务器公共ip 登陆,登陆需要输入实例密码,注意windows用户需要安装xshell

#用pycharm上传代码

  • Tools->Deployment->Configuration...
  • Add->SFTP
  • 配置Connection连接远程服务器
  • 配置Mappings,本地项目的文件和远程服务的目录对应,注意远程服务器的目录需要自己建立
  • 右击需要上传的项目目录->deployment->upload,注意如果只上传某一个文件或目录则只右击需要上传的文件或者目录

#环境安装

#安装python3.7

  • 1.安装依赖
yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel gcc gcc-c++ openssl-devel libffi-devel python-devel mariadb-devel
  • 2.下载源码
wget https://www.python.org/ftp/python/3.7.3/Python-3.7.3.tgz tar -xzvf Python-3.7.3.tgz -C /tmp cd /tmp/Python-3.7.3/ 
  • 3.把Python3.7安装到 /usr/local 目录
./configure --prefix=/usr/localmakemake install #这一步比较耗时
  • 4.更改/usr/bin/python链接
ln -s /usr/local/bin/python3.7 /usr/bin/python3ln -s /usr/local/bin/pip3.7 /usr/bin/pip3

#安装新版sqlite

  • 1.下载源码
wget https://www.sqlite.org/2019/sqlite-autoconf-3270200.tar.gztar -zxvf sqlite-autoconf-3270200.tar.gz -C /tmp cd /tmp/sqlite-autoconf-3270200/ 
  • 2.把sqlite安装到 /usr/local 目录
./configure --prefix=/usr/localmakemake install #这一步比较耗时
  • 3.建立软链接
#如果文件已经存在则备份mv /usr/bin/sqlite3 /usr/bin/sqlite3_old#建立软链接ln -s /usr/local/bin/sqlite3 /usr/bin/sqlite3
  • 4.修改 ~/.bashrc文件
export LD_LIBRARY_PATH="/usr/local/lib"
  • 5.从新加载~/.bashrc文件
source ~/.bashrc

#安装virtualenvwrapper

  • 1.安装
export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3yum install python-setuptools python-develpip3 install virtualenvwrapper
  • 2.修改~/.bashrc文件
export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3export WORKON_HOME=$HOME/.virtualenvssource /usr/local/bin/virtualenvwrapper.sh
  • 3.从新加载~/.bashrc文件
source ~/.bashrc

TIP

如果出现找不到文件,可以使用以下命令查找文件的位置

sudo find / -name 文件名
  • 4.新建虚拟环境
mkvirtualenv -p python3 pycms
  • 5.进入虚拟环境
workon pycms
  • 6.安装pip包

注意,需要把requirements.txt文件上传到服务器之后运行

pip3 install -r requirements.txt
  • 7.拉取所有需要的static file 到同一个目录

确保settings.py文件中有以下配置

STATIC_ROOT = os.path.join(BASE_DIR, "static/")

然后运行命令

python3 manage.py collectstatic
  • 8.启动项目

在项目的根目录下执行

python3 manage.py runserver 0.0.0.0:80
  • 9.通过公网ip地址访问项目

#域名解析

设置记录类型为A,设置记录值为对应的外网ip

#uwsgi+nignx部署项目

#安装uwsgi

web 容器,拉起项目

  • 1.安装
pip3 install uwsgi
  • 2.测试

在项目的根目录运行

#项目名称.wsgiuwsgi --http :8000 --module project.wsgi
  • 3.配置

新建 项目根目录/config/uwsgi.ini

# uwsgi.ini file[uwsgi]# 表示需要操作的目录,也就是项目的目录chdir = /root/pycms# Django的wsgi file# wsgi文件的路径,名称和项目的应用名称一直module = project.wsgi# process-related settings# mastermaster = true# maximum number of worker processes# 进程数processes = 10# the socket (use the full path to be safe)socket = 127.0.0.1:8000# chmod-socket = 664# clear environment on exitvacuum = true# 虚拟环境的目录virtualenv = /root/.virtualenvs/pycms# 运行log存放文件logto = /tmp/uwsgi.log
  • 4.启动uwsgi
workon pycms# -d表示后台运行uwsgi -d -i 项目根目录/config/uwsgi.ini
  • 5.查看启动
ps aux|grep uwsgi

TIP

注意:用配置文件启动的uwsgi不能直接在浏览器中访问

  • 6.查看端口
netstat -lpnt
  • 6.关闭uwsgi
killall -9 uwsgi

#安装nginx

nginx主要用来反向代理,端口转发

  • 1.安装
sudo yum install epel-releasesudo yum install nginx
  • 2.启动
sudo systemctl start nginx
  • 3.新建 项目根目录/config/nginx.conf
# the upstream component nginx needs to connect toupstream django {server 127.0.0.1:8000; #转发到的端口,同uwsig配置的端口一直}# configuration of the serverserver {# 监听的端口listen 80;# 域名或者ip地址,如果共存用空格隔开server_name 你的ip地址; charset utf-8;# 上传文件大小设置client_max_body_size 75M; location /media { alias 项目根目录/media; # 指向django的media目录}location /static { alias 项目根目录/static; # 指向django的static目录}# 非静态资源请求转发到djangolocation / { uwsgi_pass django; include uwsgi_params; # the uwsgi_params file you installed}}
  • 4.将该配置文件加入到nginx的启动配置文件中
sudo ln -s pycms_nginx.conf /etc/nginx/conf.d/
  • 修改 /etc/nginx/nginx.conf
user root
  • 6.启动nginx
sudo systemctl start nginx
  • 7.重启nigx
sudo systemctl restart nginx

#附录:pycharm常用调试技巧

  • 在需要调试的代码对应的行号处单击设置断点
  • 右键以debug模式运行代码,代码会暂停在端点处,常见调试按钮F8(第二个按钮) 执行下一步F7(第三个按钮) 进入函数内部Shift+F8(第六个按钮) 跳出函数option + F9(最后一个按钮) 直接跳转到下一个断点处
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值