大家好,又见面了,我是你们的朋友全栈君。
Django
一、介绍
1、简介
是用python语言写的开源web开发框架,并遵循MVC设计。
Django的主要目的是简便、快速的开发数据库驱动的网站。
2、特点
1) 重量级框架
2)MVT模式
- MVC
- 其核心思想是分工、解耦,让不同的代码块之间降低耦合,增强代码的可扩展性和可移植性,实现向后兼容。
- M全拼为Model,主要封装对数据库层的访问,对数据库中的数据进行增、删、改、查操作。
- V全拼为View,用于封装结果,生成页面展示的html内容。
- C全拼为Controller,用于接收请求,处理业务逻辑,与Model和View交互,返回结果。
- MVT
- M全拼为Model,与MVC中的M功能相同,负责和数据库交互,进行数据处理。
- V全拼为View,与MVC中的C功能相同,接收请求,进行业务处理,返回应答。
- T全拼为Template,与MVC中的V功能相同,负责封装构造要返回的html。
二、工程搭建
1、创建工程
创建工程命令
代码语言:javascript复制django-admin startproject 工程名称
工程目录说明
- settings.py 是项目的整体配置文件。
- urls.py 是项目的URL配置文件。
- wsgi.py 是项目与WSGI兼容的Web服务器入口。
- manage.py 是项目管理文件,通过它管理项目
运行开发服务器
代码语言:javascript复制python manage.py runserver ip:端口
或:python manage.py runserver
# 可以不写IP和端口,默认IP是127.0.0.1,默认端口为8000
2、创建子应用
创建
代码语言:javascript复制python manage.py startapp 子应用名称
# 例如创建一个user子应用模块
'''
cd ~/Desktop/code/demo
python manage.py startapp users
'''
子应用目录说明
- admin.py 文件跟网站的后台管理站点配置相关。
- apps.py 文件用于配置当前子应用的相关信息。
- migrations 目录用于存放数据库迁移历史文件。
- models.py 文件用户保存数据库模型类。
- tests.py 文件用于开发测试用例,编写单元测试。
- views.py 文件用于编写Web应用视图。
注册安装子应用
代码语言:javascript复制注册安装一个子应用的方法,即是将子应用的配置信息文件apps.py中的Config类添加到INSTALLED_APPS列表中。
# 例如
'''
INSTALLED_APPS = [
...
'users.apps.UsersConfig',
]
'''
3、创建视图
创建
代码语言:javascript复制# 在views.py中编写视图代码
from django.http import HttpResponse
def index(request):
"""
index视图
:param request: 包含了请求信息的请求对象
:return: 响应对象
"""
return HttpResponse("hello the world!")
'''
说明:
1、视图函数的第一个传入参数必须定义,用于接收Django构造的包含了请求数据的HttpReqeust对象,通常名为request。
2、视图函数的返回值必须为一个响应对象,不能像Flask一样直接返回一个字符串,可以将要返回的字符串数据放到一个HTTPResponse对象中。
'''
定义路由URL
- 在子应用中新建一个urls.py文件用于保存该应用的路由。
- 在users/urls.py文件中定义路由信息。 from django.conf.urls import url from . import views urlpatterns是被django自动识别的路由列表变量 urlpatterns = [ # 每个路由信息都需要使用url函数来构造 # url(路径, 视图) url(r’^index/$’, views.index), ]
- 在工程总路由demo/urls.py中添加子应用的路由数据。
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls), # django默认包含的
# 添加
url(r'^users/', include('users.urls')),
]
# 使用include来将子应用users里的全部路由包含进工程路由中
# r'^users/' 决定了users子应用的所有路由都已/users/开头,如我们刚定义的视图index,其最终的完整访问路径为/users/index/。
# include函数除了可以传递字符串之外,也可以直接传递应用的urls模块
- 启动运行 python manage.py runserver
三、配置、静态文件与路由
1、 配置文件
BASE_DIR
代码语言:javascript复制BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
- 当前工程的根目录,Django会依此来定位工程内的相关文件,我们也可以使用该参数来构造文件路径。
DEBUG
- 调试模式,创建工程后初始值为True,即默认工作在调试模式下。
- 作用:
- 修改代码文件,程序自动重启
- Django程序出现异常时,向前端显示详细的错误追踪信息.
- 注意:部署线上运行的Django不要运行在调式模式下,记得修改DEBUG=False .
本地语言与时区
- 中国大陆地区使用简体中文,时区使用亚洲/上海时区 LANGUAGE_CODE = ‘zh-hans’ # 语言 TIME_ZONE = ‘Asia/Shanghai’ # 时区
2、静态文件
- 推荐放在项目的根目录下,方便管理。
- 为了提供静态文件,需要配置两个参数:
- STATICFILES_DIRS 存放查找静态文件的目录
- STATIC_URL 访问静态文件的URL前缀
- 示例 1) 在项目根目录下创建static_files目录来保存静态文件。 2) 在demo/settings.py中修改静态文件的两个参数为 STATIC_URL = ‘/static/’ STATICFILES_DIRS = [ os.path.join(BASE_DIR, ‘static_files’), ] 3)此时在static_files添加的任何静态文件都可以使用网址 /static/文件在static_files中的路径 来访问了。
- 注意 Django 仅在调试模式下(DEBUG=True)能对外提供静态文件。 当DEBUG=False工作在生产模式时,Django不再对外提供静态文件,需要是用collectstatic命令来收集静态文件并交由其他静态文件服务器来提供。
3、路由说明
路由定义位置
- Django的主要路由信息定义在工程同名目录下的urls.py文件中,该文件是Django解析路由的入口。
- 每个子应用为了保持相对独立,可以在各个子应用中定义属于自己的urls.py来保存该应用的路由。然后用主路由文件包含各应用的子路由数据。
路由解析顺序
- Django在接收到一个请求时,从主路由文件中的urlpatterns列表中以由上至下的顺序查找对应路由规则,如果发现规则为include包含,则再进入被包含的urls中的urlpatterns列表由上至下进行查询。
- 值得关注的由上至下的顺序,有可能会使上面的路由屏蔽掉下面的路由,带来非预期结果。 需要注意定义路由的顺序,避免出现屏蔽效应。
路由命名与reverse反解析(逆向)
路由命名
- 在使用include函数定义路由时,可以使用namespace参数定义路由的命名空间,如 url(r’^users/’, include(‘users.urls’, namespace=‘users’)), 命名空间表示,凡是users.urls中定义的路由,均属于namespace指明的users名下。 命名空间的作用:避免不同应用中的路由使用了相同的名字发生冲突,使用命名空间区别开。
- 在定义普通路由时,可以使用name参数指明路由的名字,如 urlpatterns = [ url(r’^index/$’, views.index, name=‘index’), url(r’^say’, views.say, name=‘say’), ]
reverse反解析 使用reverse函数,可以根据路由名称,返回具体的路径,如: from django.urls import reverse # 注意导包路径
代码语言:javascript复制def index(request):
return HttpResponse("hello the world!")
def say(request):
url = reverse('users:index') # 返回 /users/index/
print(url)
return HttpResponse('say')
- 对于未指明namespace的,reverse(路由name)
- 对于指明namespace的,reverse(命名空间namespace:路由name)
路径结尾斜线/的说明
Django中定义路由时,通常以斜线/结尾,其好处是用户访问不以斜线/结尾的相同路径时,Django会把用户重定向到以斜线/结尾的路径上,而不会返回404不存在 。
代码语言:javascript复制urlpatterns = [
url(r'^index/$', views.index, name='index'),
]
四、请求与相应
1、请求
1)URL路径参数
可以使用正则表达式提取参数的方法从URL中获取请求参数,直接传递到视图的传入参数中。
- 未命名参数按定义顺序传递 url(r’^weather/([a-z] )/(d{4})/$’, views.weather), def weather(request, city, year): print(‘city=%s’ % city) print(‘year=%s’ % year) return HttpResponse(‘OK’)
- 命名参数按名字传递 url(r’^weather/(?P[a-z] )/(?Pd{4})/$’, views.weather), def weather(request, year, city): print(‘city=%s’ % city) print(‘year=%s’ % year) return HttpResponse(‘OK’)
2)QueryDict对象
定义在django.http.QueryDict
HttpRequest对象的属性GET、POST都是QueryDict类型的对象
QueryDict类型的对象用来处理同一个键带有多个值的情况
- 方法get():根据键获取值 dict.get(‘键’,默认值) 可简写为 dict[‘键’] # 说明: # 如果一个键同时拥有多个值将获取最后一个值 # 如果键不存在则返回None值,可以设置默认值进行后续处理
- 方法getlist():根据键获取值,值以列表返回,可以获取指定键的所有值 如果键不存在则返回空列表[],可以设置默认值进行后续处理 dict.getlist(‘键’,默认值)
3)查询字符串
通过request.GET属性获取,返回QueryDict对象。
代码语言:javascript复制# /qs/?a=1&b=2&a=3
def qs(request):
a = request.GET.get('a')
b = request.GET.get('b')
alist = request.GET.getlist('a')
print(a) # 3
print(b) # 2
print(alist) # ['1', '3']
return HttpResponse('OK')
# 重要:查询字符串不区分请求方式,即假使客户端进行POST方式的请求,依然可以通过request.GET获取请求中的查询字符串数据。
4)请求体
请求体数据格式:表单类型字符串、JSON字符串、XML字符串
请求方式:POST/PUT/PATCH/DELETE
表单类型 通过request.POST属性获取,返回QueryDict对象。 def get_body(request): a = request.POST.get(‘a’) b = request.POST.get(‘b’) alist = request.POST.getlist(‘a’) print(a) print(b) print(alist) return HttpResponse(‘OK’) # 重要:request.POST只能用来获取POST方式的请求体表单数据。
非表单类型 通过request.body属性获取最原始的请求体数据,自己按照请求体格式(JSON、XML等)进行解析。request.body返回bytes类型。 # 请求体中的数据 {“a”: 1, “b”: 2}
代码语言:javascript复制import json
def get_body_json(request):
json_str = request.body
json_str = json_str.decode() # python3.6 无需执行此步
req_data = json.loads(json_str)
print(req_data['a'])
print(req_data['b'])
return HttpResponse('OK')
请求头
request.META为字典类型。
常见的请求头:
- CONTENT_LENGTH – The length of the request body (as a string).
- CONTENT_TYPE – The MIME type of the request body.
- HTTP_ACCEPT – Acceptable content types for the response.
- HTTP_ACCEPT_ENCODING – Acceptable encodings for the response.
- HTTP_ACCEPT_LANGUAGE – Acceptable languages for the response.
- HTTP_HOST – The HTTP Host header sent by the client.
- HTTP_REFERER – The referring page, if any.
- HTTP_USER_AGENT – The client’s user-agent string.
- QUERY_STRING – The query string, as a single (unparsed) string.
- REMOTE_ADDR – The IP address of the client.
- REMOTE_HOST – The hostname of the client.
- REMOTE_USER – The user authenticated by the Web server, if any.
- REQUEST_METHOD – A string such as “GET” or “POST”.
- SERVER_NAME – The hostname of the server.
- SERVER_PORT – The port of the server (as a string). 具体使用: def get_headers(request): print(request.META[‘CONTENT_TYPE’]) return HttpResponse(‘OK’)
其他
- method:一个字符串,表示请求使用的HTTP方法,常用值包括:‘GET’、‘POST’。
- user:请求的用户对象。
- path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分。
- encoding:一个字符串,表示提交的数据的编码方式。
- 如果为None则表示使用浏览器的默认设置,一般为utf-8。
- 这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值。
- FILES:一个类似于字典的对象,包含所有的上传文件。
2、响应
HttpResponse
django.http.HttpResponse来构造响应对象
代码语言:javascript复制HttpResponse(content=响应体, content_type=响应体数据类型, status=状态码)
HttpResponse子类
Django提供了一系列HttpResponse的子类,可以快速设置状态码
- HttpResponseRedirect 301
- HttpResponsePermanentRedirect 302
- HttpResponseNotModified 304
- HttpResponseBadRequest 400
- HttpResponseNotFound 404
- HttpResponseForbidden 403
- HttpResponseNotAllowed 405
- HttpResponseGone 410
- HttpResponseServerError 500
JsonResponse
- 返回json字符串
- 设置响应头Content-Type为 application/json
redirect重定向
代码语言:javascript复制from django.shortcuts import redirect
def demo_view(request):
return redirect('/index.html')
3、Cookie
特点:
- 键值对格式的字符串,存储于浏览器中
- 基于域名安全,不同域名的Cookie是不能互相访问的,同源策略
- 浏览器会将cookie信息包含在请求报文中,发给服务器
设置Cookie
代码语言:javascript复制HttpResponse.set_cookie(cookie名, value=cookie值, max_age=cookie有效期)
# max_age 单位为秒,默认为None。如果是临时cookie,可将max_age设置为None。
读取Cookie
可以通过HttpRequest对象的COOKIES属性来读取本次请求携带的cookie值。request.COOKIES为字典类型。
代码语言:javascript复制def demo_view(request):
cookie1 = request.COOKIES.get('itcast1')
print(cookie1)
return HttpResponse('OK')
删除
request.delete_cokkie(键)
4、Session
- 写:request.session[‘键’]=值
- 读:request.session.get(‘键’,默认值)
- 删
- 删除值:request.session.clear()
- 删除整条数据:request.session.flush()
- 删除指定的键及值:del request.sessioon[‘键’]
- 设置有效期:request.session.set_expiry(value)
- 如果value是一个整数,session将在value秒没有活动后过期。
- 如果value为0,那么用户session的Cookie将在用户的浏览器关闭时过期。
- 如果value为None,那么session有效期将采用系统默认值,默认为两周,可以通过在settings.py中设置SESSION_COOKIE_AGE来设置全局默认值。
五、类视图与中间件
1、类视图
定义:使用类来定义的视图
好处:
- 可读性好
- 更高的复用性
使用 from django.view.generic import View 配置路由时,使用类视图的as_view()方法来添加
原理 在注册路由规则时类.as_view()返回方法名 在请求路径与正则匹配成功后,方法会被执行 调用dispatch()方法 根据请求方式名称获取方法 执行方法
使用装饰器
在URL配置中装饰 此种方法会为类视图中的所有请求方法都加上装饰器行为,不建议使用
类视图中装饰 method_decorator装饰器使用name参数指明被装饰的方法 # 为全部请求方法添加装饰器 @method_decorator(my_decorator, name=‘dispatch’) class DemoView(View): def get(self, request): print(‘get方法’) return HttpResponse(‘ok’)
代码语言:javascript复制 def post(self, request):
print('post方法')
return HttpResponse('ok')
# 为特定请求方法添加装饰器
@method_decorator(my_decorator, name='get')
class DemoView(View):
def get(self, request):
print('get方法')
return HttpResponse('ok')
def post(self, request):
print('post方法')
return HttpResponse('ok')
如果需要为类视图的多个方法添加装饰器,但又不是所有的方法(为所有方法添加装饰器参考上面例子),可以直接在需要添加装饰器的方法上使用method_decorator from django.utils.decorators import method_decorator
代码语言:javascript复制# 为特定请求方法添加装饰器
class DemoView(View):
@method_decorator(my_decorator) # 为get方法添加了装饰器
def get(self, request):
print('get方法')
return HttpResponse('ok')
@method_decorator(my_decorator) # 为post方法添加了装饰器
def post(self, request):
print('post方法')
return HttpResponse('ok')
def put(self, request): # 没有为put方法添加装饰器
print('put方法')
return HttpResponse('ok')
类视图Mixin扩展类
2、中间件
Django中的中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出。
代码实现 定义一个中间件工厂函数,然后返回一个可以别调用的中间件。 中间件工厂函数需要接收一个可以调用的get_response对象。 返回的中间件也是一个可以被调用的对象,并且像视图一样需要接收一个request对象参数,返回一个response对象。 def simple_middleware(get_response): # 此处编写的代码仅在Django第一次配置和初始化的时候执行一次。
代码语言:javascript复制 def middleware(request):
# 此处编写的代码会在每个请求处理视图前被调用。
response = get_response(request)
# 此处编写的代码会在每个请求处理视图之后被调用。
return response
return middleware
定义好中间件后,需要在settings.py 文件中添加注册中间件 MIDDLEWARE = [ … ‘users.middleware.my_middleware’, # 添加中间件 ] 注意:Django运行在调试模式下,中间件init部分有可能被调用两次。
执行流程
- 在请求视图被处理前,中间件由上至下依次执行
- 在请求视图被处理后,中间件由下至上依次执行
六、模板
1、配置
settings.py配置文件中修改TEMPLATES中的DIRS
2、定义
3、渲染
- 调用模板两步骤:
- loader.get_template(模板文件在模板目录中的相对路径)–> 返回模板对象
- 模板对象.render(contex=None,request=None)–>返回渲染后的html文本字符串
- Django提供了一个函数render可以简写上述代码。
- render(request对象, 模板文件路径, 模板数据字典) from django.shortcuts import render def index(request): context={‘city’: ‘北京’} return render(request,‘index.html’,context)
4、语法
{ {变量}}-变量
{%for%}…{%endfor%}
{%if%}…{%elif%}…{%else%}…{%endif%}
== != < > <= >=比较运算符
and or not布尔运算符
注意:运算符左右两侧不能紧挨变量或常量,必须有空格
变量|过滤器:参数过滤器
- safe,禁用转义,告诉模板这个变量是安全的,可以解释执行
- length,长度,返回字符串包含字符的个数,或列表、元组、字典的元素个数。
- default,默认值,如果变量不存在时则返回默认值。
- date,日期,用于对日期类型的值进行字符串格式化,常用的格式化字符如下:
- Y表示年,格式为4位,y表示两位的年。
- m表示月,格式为01,02,12等。
- d表示日, 格式为01,02等。
- j表示日,格式为1,2等。
- H表示时,24进制,h表示12进制的时。
- i表示分,为0-59。
- s表示秒,为0-59。 value|date:“Y年m月j日 H时i分s秒” {#…#}单行注释 {%comment%}…{%endcomment%}多行注释
5、模板继承
父模板:{%block%}…{%endblock%}
子模板:{%extends “父模板路径”%}
写在子模板文件的第一行
七、数据库
ORM框架:
- 通过类和类对象就能操作它对所对应的表格中的数据
- 根据设计的类自动生成数据库中的表格
数据库迁移:
- python manage.py makemigrations
- python manage.py migrate
数据库的操作
1.增
- save 对象.save()
- create 模型类.objects.create()
2.查
基本查询
- get 查询单一结果,不存在抛出 模型类.DoesNotExist 异常
- all 多个结果
- count 查询结果数量
过滤查询
- filter 过滤多个结果
- exclude 排除
- get 过滤单一结果
过滤条件的表达语法 属性名称__比较运算符=值
- exact
- contains
- startwith、endwith
- isnull
- in
- gt/gte/lt/lte
- year/month/day/week_day/hour/minute/second
F对象 F( 属性名) 属性比较
Q对象 Q(属性名__运算符=值) 实现逻辑或or的查询,需要使用Q()对象结合|运算符 Q对象前可以使用~操作符,表示非not # 例:查询阅读量大于20,或编号小于3的图书,只能使用Q对象实现 from django.db.models import Q BookInfo.objects.filter(Q(bread__gt=20) | Q(pk__lt=3))
聚合函数 使用aggregate()过滤器调用聚合函数,返回字典类型的数据
- Avg
- Count
- Max
- Min
- Sum
排序
- order_by
- 默认升序,-降序
关联查询
一到多:一对应的模型类对象.多对应的模型类名小写_set b = BookInfo.objects.get(id=1) b.heroinfo_set.all()
多到一:多对应的模型类对象.多对应的模型类中的关系属性名 h = HeroInfo.objects.get(id=1) h.hbook
访问一对应的模型类关联对象的id 多对应的模型类对象.关联类属性_id
关联过滤查询
由多模型类条件查询一模型类数据: 关联模型类名小写__属性名__条件运算符=值
代码语言:javascript复制# 例句:查询图书,要求图书中英雄的描述包含"八"
BookInfo.objects.filter(heroinfo__hcomment__contains='八')
由一模型类条件查询多模型类数据: 一模型类关联属性名__一模型类属性名__条件运算符=值
代码语言:javascript复制# 查询图书阅读量大于30的所有英雄
HeroInfo.objects.filter(hbook__bread__gt=30)
3.改
- save
- update 使用模型类.objects.filter().update(),会返回受影响的行数
4.删
- 模型类对象delete
- 模型类.objects.filter().delete()
查询集 QuerySet
1、概念:从数据库中获取的对象集合
过滤器方法:
- all()
- filter()
- exclude()
- order_by()
- exists():判断查询集中是否有数据,有返回Ture,无返回False
2、特性
- 惰性执行:创建查询集的时候不会调用数据库,调用数据的时候访问,迭代、序列化、if合用
- 缓存
3、限制查询集
对查询集进行下标或切片操作,切片后返回新的查询集,不会立即执行
管理器Manageer
1、自定义管理器
- 修改原始查询集,重写all()方法
- booktest/models.py文件中 #图书管理器 class BookInfoManager(models.Manager): def all(self): #默认查询未删除的图书信息 #调用父类的成员语法为:super().方法名 return super().filter(is_delete=False)
- 在模型类BookInfo中定义管理器 class BookInfo(models.Model): … books = BookInfoManager()
- 使用方法 BookInfo.books.all()
- 在管理器类中补充定义新的方法
- 打开booktest/models.py文件,定义方法create
- 为模型类BookInfo定义管理器books语法如下
- 调用方法
八、Admin
使用
1、管理界面本地化
代码语言:javascript复制settings.py中设置语言和时间
2、创建超级管理员
代码语言:javascript复制python manage.py createsuperuser
> 修改密码:
>
> python manage.py changepassword 用户名
3、App应用配置
代码语言:javascript复制在settings.py中INSTALLED_APPS列表中添加此类
4、注册模型类
代码语言:javascript复制# 在booktest/admin.py 文件中编写代码:
from django.contrib import admin
from booktest.models import BookInfo,HeroInfo
admin.site.register(BookInfo)
admin.site.register(HeroInfo)
5、定义与使用Admin管理类
定义:继承自admin.ModelAdmin
使用:
- 注册参数 admin.site.register(BookInfo,BookInfoAdmin)
- 装饰器 @admin.register(BookInfo) class BookInfoAdmin(admin.ModelAdmin): pass
编辑
1、调整列表页展示
页大小:list_per_page = 100
操作选项的位置:
- actions_on_top = True
- actions_on_bottom = True
列表中的列:list_display = [模型字段1,模型字段2]
将方法作为列:short_description属性 # models.py中: class BookInfo(models.Model): … def pub_date(self): return self.bpub_date.strftime(’%Y年%m月%d日’)
代码语言:javascript复制 pub_date.short_description = '发布日期' # 设置方法字段在admin中显示的标题
# admin.py中:
class BookInfoAdmin(admin.ModelAdmin):
...
list_display = ['id','btitle','pub_date']
# 说明:
方法列是不能排序的,需要排序:
admin_order_field = 模型类字段
关联对象 在模型类中封装方法,访问关联对象的成员
右侧栏过滤器:list_filter = []
搜索框:search_fields = []
2、调整编辑页展示
- 显示字段:fields = []
- 分组显示: fieldset=( (‘组1标题’,{‘fields’:(‘字段1’,‘字段2’)}), (‘组2标题’,{‘fields’:(‘字段3’,‘字段4’)}), )
- 关联对象
- 类型InlineModelAdmin:表示在模型的编辑页面嵌入关联模型的编辑
- 子类TabularInline:表格的形式嵌入
- 子类StackedInline:块的形式嵌入
3、调整站点信息
- admin.site.site_header 设置网站页头
- admin.site.site_title 设置页面标题
- admin.site.index_title 设置首页标语
4、上传图片
pip install Pillow==4.1.0
配置 MEDIA_ROOT=os.path.join(BASE_DIR,“static_files/media”)
模型类添加字段 class BookInfo(models.Model): … image = models.ImageField(upload_to=‘booktest’, verbose_name=‘图片’, null=True)
代码语言:javascript复制# upload_to 指明该字段的图片保存在MEDIA_ROOT目录中的哪个子目录
数据库迁移: python manage.py makemigrations python manage.py migrate
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。