首页
畅所欲言
友情链接
壁纸大全
数据统计
推荐
工具箱
在线白板
Search
1
职教云小助手重构更新,职教云助手最新版下载地址【已和谐】
13,307 阅读
2
职教云-智慧职教,网课观看分析(秒刷网课)
10,905 阅读
3
gradle-5.4.1-all.zip下载
8,831 阅读
4
职教云-智慧职教,签到补签分析(逆天改命系列)
7,816 阅读
5
一个优秀的程序员从写文档开始:免费领14个月语雀云笔记会员
6,866 阅读
学习笔记
Web
Python
转载文章
算法刷题
JS逆向
综合笔记
安卓
物联网
Java
C
资源收集
软件收藏
网络资源
影视专辑
TED英语角
随便写写
随手拍
登录
/
注册
Search
Lan
累计撰写
623
篇文章
累计收到
612
条评论
首页
栏目
学习笔记
Web
Python
转载文章
算法刷题
JS逆向
综合笔记
安卓
物联网
Java
C
资源收集
软件收藏
网络资源
影视专辑
TED英语角
随便写写
随手拍
页面
畅所欲言
友情链接
壁纸大全
数据统计
推荐
工具箱
在线白板
搜索到
36
篇与
的结果
2021-07-19
论文格式
结构论文一般由题名、作者、目录、摘要、关键词、正文、参考文献和附录等部分组成,其中部分组成(例如附录)可有可无。论文各组成的排序为:题名、作者、摘要、关键词、英文题名、英文摘要、英文关键词、正文、参考文献、附录和致谢。题目题目规范题名应简明、具体、确切,能概括论文的特定内容,有助于选定关键词,符合编制题录、索引和检索的有关原则。命题方式简明扼要,提纲挈领。英文题名方法英文题名以短语为主要形式,尤以名词短语最常见,即题名基本上由一个或几个名词加上其前置和(或)后置定语构成;短语型题名要确定好中心词,再进行前后修饰。各个词的顺序很重要,词序不当,会导致表达不准。一般不要用陈述句,因为题名主要起标示作用,而陈述句容易使题名具有判断式的语义,且不够精炼和醒目。少数情况(评述性、综述性和驳斥性)下可以用疑问句做题名,因为疑问句有探讨性语气,易引起读者兴趣。同一篇论文的英文题名与中文题名内容上应一致,但不等于说词语要一一对应。在许多情况下,个别非实质性的词可以省略或变动。国外科技期刊一般对题名字数有所限制,有的规定题名不超过2行,每行不超过42个印刷符号和空格;有的要求题名不超过14个词。这些规定可供我们参考。在论文的英文题名中。凡可用可不用的冠词均不用。作者书名规范作者署名置于题名下方,团体作者的执笔人,也可标注于篇首页脚位置。有时,作者姓名亦可标注于正文末尾。示例:王军 ××师范大学物理系,北京 100875; 张红 ××教育学院物理系,北京 100011(注释:后面的数字是该学院的邮编号码)目录目录是论文中主要段落的简表。(短篇论文不必列目录)摘要摘要是文章主要内容的摘录,要求短、精、完整。字数少可几十字,多不超过三百字为宜。随着计算机技术和因特网的迅猛发展,网上查询、检索和下载专业数据已成为当前科技信息情报检索的重要手段,对于网上各类全文数据库或文摘数据库,论文摘要的索引是读者检索文献的重要工具,为科技情报文献检索数据库的建设和维护提供方便。摘要是对论文综合的介绍,使人了解论文阐述的主要内容。论文发表后,文摘杂志或各种数据库对摘要可以不作修改或稍作修改而直接利用,让读者尽快了解论文的主要内容,以补充题名的不足,从而避免他人编写摘要可能产生的误解、欠缺甚至错误。所以论文摘要的质量高低,直接影响着论文的被检索率和被引频次。规范摘要是对论文的内容不加注释和评论的简短陈述,要求扼要地说明研究工作的目的、研究方法和最终结论等,重点是结论,是一篇具有独立性和完整性的短文,可以引用、推广。关键词关键词是从论文的题名、提要和正文中选取出来的,是对表述论文的中心内容有实质意义的词汇。关键词是用作计算机系统标引论文内容特征的词语,便于信息系统汇集,以供读者检索。每篇论文一般选取3-8个词汇作为关键词,另起一行,排在“摘要”的左下方。主题词是经过规范化的词,在确定主题词时,要对论文进行主题分析,依照标引和组配规则转换成主题词表中的规范词语。(参见《汉语主题词表》和《世界汉语主题词表》)。规范关键词是反映论文主题概念的词或词组,通常以与正文不同的字体字号编排在摘要下方。一般每篇可选3~8个,多个关键词之间用分号分隔,按词条的外延(概念范围)层次从大到小排列。关键词一般是名词性的词或词组,个别情况下也有动词性的词或词组。应标注与中文关键词对应的英文关键词。编排上中文在前,外文在后。中文关键词前以“关键词:”或“[关键词]”作为标识;英文关键词前以“Key words:”作为标识。关键词应尽量从国家标准《汉语主题词表》中选用;未被词表收录的新学科、新技术中的重要术语和地区、人物、文献等名称,也可作为关键词标注。关键词应采用能覆盖论文主要内容的通用技术词条。关键词方法关键词的一般选择方法是:由作者在完成论文写作后,从其题名、层次标题和正文(出现频率较高且比较关键的词)中选出来。论文正文要点引言:引言又称前言、序言和导言,用在论文的开头。引言一般要概括地写出作者意图,说明选题的目的和意义,并指出论文写作的范围。引言要短小精悍、紧扣主题。论文正文:正文是论文的主体,正文应包括论点、论据、论证过程和结论。主体部分包括以下内容:a.提出问题-论点;b.分析问题-论据和论证;c.解决问题-论证方法与步骤;d.结论。为了做到层次分明、脉络清晰,常常将正文部分分成几个大的段落。这些段落即所谓逻辑段,一个逻辑段可包含几个小逻辑段,一个小逻辑段可包含一个或几个自然段,使正文形成若干层次。论文的层次不宜过多,一般不超过五级。要求以毕业论文为例,现说明论文正文版面格式:①正文部分与“关键词”行间空两行;②汉语正文文字采用小四号宋体;正文英语正文文字采用Times New Roman12号,标题汉语采用四号黑体,标题英语采用Times New Roman14号,每段首起空两格,1.25倍行距;③段落间层次要分明,题号使用要规范。理工类专业毕业设计,可以结合实际情况确定具体的序号与层次要求;④文字要求:文字通顺,语言流畅,无错别字,无违反政治上的原则问题与言论,要采用计算机打印文稿,统一采用A4纸张;⑤图表要求:所有图表、线路图、流程图、程序框图、示意图等不准用徒手图,必须按国家规定的工作要求采用计算机或手工绘图,图表中的文字汉语用小五号宋体;英语采用Times New Roman10. 5号;图表编号要连续,如图1、图2等,表1、表2等;图的编号放在图的下方,表的编号放在表的上方,表的左右两边不能有边;⑥字数要求:一般不少于1500(按老师要求);⑦学年论文引用的观点、数据等要注明出处,一律采用尾注。格式要求[1]文稿用word文件(页面A4),统一用宋体排版。页面设置纸型:A4标准纸 方向:纵向页边距:左3cm 右2.5cm;上,下边距为默认值:上2.8cm 下2.5cm页眉1.5cm,页脚1.5cm格式正文行距:(多倍行距)1.25倍字号中英文题目:二号黑体加粗居中;英文(位于中文标题下方),二号Time New Roman字体, 加粗居中。中英文摘要、关键词、参考文献的具体内容:五号字图表要求图面整洁,布局合理,线条粗细均匀,弧线连接光滑,尺寸标注规范,符合制图标准.插图和表格均需有编号和标题,图标题为五号字,表标题为小四号.摘自百度百科:https://baike.baidu.com/item/%E8%AE%BA%E6%96%87%E6%A0%BC%E5%BC%8F/5969051
2021年07月19日
232 阅读
0 评论
0 点赞
2021-05-28
python PIL/cv2/base64相互转换
PIL和cv2是python中两个常用的图像处理库,PIL一般是anaconda自带的,cv2是opencv的python版本。base64在网络传输图片的时候经常用到。PIL读取、保存图片方法from PIL import Image img = Image.open(img_path) img.save(img_path2)cv2读取、保存图片方法import cv2 img = cv2.imread(img_path) cv2.imwrite(img_path2, img)图片文件打开为base64import base64 def img_base64(img_path): with open(img_path,"rb") as f: base64_str = base64.b64encode(f.read()) return base64_str1、PIL和cv2转换PIL转cv2import cv2 from PIL import Image import numpy as np def pil_cv2(img_path): image = Image.open(img_path) img = cv2.cvtColor(np.asarray(image),cv2.COLOR_RGB2BGR) return imgcv2转PILimport cv2 from PIL import Image def cv2_pil(img_path): image = cv2.imread(img_path) image = Image.fromarray(cv2.cvtColor(image,cv2.COLOR_BGR2RGB)) return image2、PIL和base64转换##PIL转base64 import base64 from io import BytesIO def pil_base64(image): img_buffer = BytesIO() image.save(img_buffer, format='JPEG') byte_data = img_buffer.getvalue() base64_str = base64.b64encode(byte_data) return base64_strbase64转PILimport base64 from io import BytesIO from PIL import Image def base64_pil(base64_str): image = base64.b64decode(base64_str) image = BytesIO(image) image = Image.open(image) return imagecv2和base64转换import cv2def cv2_base64(image): base64_str = cv2.imencode('.jpg',image)[1].tostring() base64_str = base64.b64encode(base64_str)return base64_str base64转cv2import base64 import numpy as np import cv2def base64_cv2(base64_str): imgString = base64.b64decode(base64_str) nparr = np.fromstring(imgString,np.uint8) image = cv2.imdecode(nparr,cv2.IMREAD_COLOR) return image
2021年05月28日
360 阅读
0 评论
0 点赞
2021-05-22
django使用jwt进行身份验证
前言使用django-rest-framework开发api并使用json web token进行身份验证在这里使用django-rest-framework-jwt这个库来帮助我们简单的使用jwt进行身份验证并解决一些前后端分离而产生的跨域问题安装django-rest-framework在终端输入以下命令安装pip install djangorestframework pip install djangorestframework-jwt在settings.py的INSTALLED_APPS中加入:INSTALLED_APPS = [ ... 'rest_framework', 'rest_framework.authtoken', # 设置token ... ]安装django-cors-headers解决api跨域请求有好几种方法,比如(jsonp,在apache或nginx中设置,在请求头里设置),我们这里使用这个包来方便的跨域pip install django-cors-headers配置settings.py文件INSTALLED_APPS = [ ... 'corsheaders', ... ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', ... ]后端配置设置过期时间还有很多配置需要自己看文档import datetime JWT_AUTH = { 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7), 'JWT_AUTH_HEADER_PREFIX': 'JWT',}修改使用jwt验证的URLfrom rest_framework_jwt.views import obtain_jwt_token url(r'^login/', obtain_jwt_token),测试1.Postman里携带用户名密码登陆可以看到jwt为我们返回的token2.Views里设置token验证购物车需要token认证才能查看class ShoppingCartViewset(viewsets.ModelViewSet): """ 购物车功能 list: 获取购物车详情 create: 加入购物车 delete: 删除购物记录 """ permission_classes = (IsAuthenticated, IsOwnerOrReadOnly) # 标记需要进行jwt验证 authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication) serializer_class = ShopCartSerializer lookup_field = "goods_id"3.使用Postman携带token访问购物车作者:人生苦短啊链接:https://www.jianshu.com/p/740a0320f960来源:简书著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
2021年05月22日
333 阅读
0 评论
0 点赞
2021-05-22
使用Django实现微信公众号用户openid登录认证
最近在用Django做一个小项目,需要将微信的用户与网站的用户进行关联,由于是微信的订阅号,没有oauth网页授权的权限,只能退而求其次,在响应中获取用户的openid,来唯一的标识用户。Django中用户的模型继承和扩展于AbstractUser,在用户模型中添加openid字段(models.py):class Users(AbstractUser): openid = models.CharField(max_length=100,blank=True,null=True,verbose_name="openid",unique=True)我们扩展了用户的模型,并使用这个模型来作为用户认证的模型,需要在setting.py文件里指定认证的模型(website是django应用的名称,非项目名称):AUTH_USER_MODEL = 'website.Users'这样,我们就能够使用上面定义的Users模型来进行用户的登录和注册操作了。一个常见默认的Django登录认证,使用的是authenticate,在此引用Django文档中的叙述:认证一个给定用户名和密码,请使用authenticate()它以关键字参数形式接收凭证,对于默认的配置它是username和password,如果密码对于给定的用户名有效它将返回一个User对象。如果密码无效,authenticate()返回None。例子:from django.contrib.auth import authenticate user = authenticate(username='john', password='secret') if user is not None: if user.is_active: print("User is valid, active and authenticated") else: print("The password is valid, but the account has been disabled!") else: print("The username and password were incorrect.")如果authenticate返回正确的User对象,我们再使用login()方法,对返回的User对象进行登录:from django.contrib.auth import login login(request,user)这样就完成了一个最基本的Django用户认证。如果我们要用其他的方式进行登录认证呢,比如电子邮箱、手机号、或是本文所说的重点:微信openid,那就需要自定义认证方式。在Django中进行自定义认证很是方便,完成一个自定义的认证只需要三步: 1、编写一个认证后端:一个认证后端是个实现两个方法的类: get_user(user_id)和authenticate(**credentials)在此,我们新建一个py文件wechatAuth.py来写openid的认证后端:from .models import Users''' 微信openid认证登录 '''class WechatOpenidAuth(object): def get_user(self,id_): try: return Users.objects.get(pk=id_) except Users.DoesNotExist: return None def authenticate(self,openid=None): try: user = Users.objects.get(openid=openid) if user is not None: return user else: return None except Users.DoesNotExist: return None 2、在配置文件setting.py中指定认证后端:在底层,Django 维护一个“认证后台”的列表。当调用django.contrib.auth.authenticate() 时,Django 会尝试所有的认证后台进行认证。如果第一个认证方法失败,Django 将尝试第二个,以此类推,直至试完所有的认证后台。使用的认证后台通过AUTHENTICATION_BACKENDS 设置指定。AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend', 'website.wechat_auth.WechatOpenidAuth',)第一个认证后端是Django默认的认证方式,因为在Web端还需要使用,所以保留,第二个就是基于openid的认证后端。 3、使用自定义的认证后端处理登录授权:同样的使用authenticate()方法和login()方法,但是我们只传入一个参数进去,就是openidfrom django.contrib.auth import login,authenticatedef auth(request,openid): try: auth =authenticate(openid=openid) login(request,auth) print("登录成功",auth) except Exception as e: print(e)这样,一个基于openid的认证就完成了。在微信的订阅号中,我们可以利用click事件返回一个文本消息或图文消息,在其链接之中带上openid的参数。这样,当用户点击链接,就可以静默地完成用户的登录了。
2021年05月22日
397 阅读
0 评论
1 点赞
2021-02-19
Google Voice保号教程
Google Voice 官方号码回收规则:https://www.google.com/intl/zh-CN/googlevoice/program-policies.html在9个月内你的Google Voice没拔打电话或接收短信,你的号码将被回收。Google不会回收已转携至Google语音服务或申请了永久使用权的号码保号方法1.主动拔打或接收语音电话两个Google Voice号码互相拔打 ,或者申请一个textnow虚拟号码拔打也行。2、拔打免费电话美国之声:+1(213)493-0288 Apple客服: +1(800)275-2273 微软客服:+1 (800) 642-7676 亚马逊客服:+1(206)266-29923、订阅短信67135 发送AUTO 回复Y AutoZone 4条/mo 555444 发送SIGNUP 回复Y 6msgs/mo 22122 发送JOIN 星巴克 2msg/mo 527365 发送join 回复yes 8msg / mo 25666 先发code 然后回复PROMO 47272 发送START 回复 OK 6msgs/mo
2021年02月19日
1,266 阅读
0 评论
0 点赞
2020-10-25
用Python处理HTML转义字符的5种方式
写爬虫是一个发送请求,提取数据,清洗数据,存储数据的过程。在这个过程中,不同的数据源返回的数据格式各不相同,有 JSON 格式,有 XML 文档,不过大部分还是 HTML 文档,HTML 经常会混杂有转移字符,这些字符我们需要把它转义成真正的字符。什么是转义字符在 HTML 中 <、>、& 等字符有特殊含义(<,> 用于标签中,& 用于转义),他们不能在 HTML 代码中直接使用,如果要在网页中显示这些符号,就需要使用 HTML 的转义字符串(Escape Sequence),例如 < 的转义字符是 <,浏览器渲染 HTML 页面时,会自动把转移字符串换成真实字符。转义字符(Escape Sequence)由三部分组成:第一部分是一个 & 符号,第二部分是实体(Entity)名字,第三部分是一个分号。 比如,要显示小于号(<),就可以写< 。Python 反转义字符串用 Python 来处理转义字符串有多种方式,而且 py2 和 py3 中处理方式不一样,在 python2 中,反转义串的模块是 HTMLParser。# python2 import HTMLParser >>> HTMLParser().unescape('a=1&b=2') 'a=1&b=2'Python3 把 HTMLParser 模块迁移到 html.parser# python3 >>> from html.parser import HTMLParser >>> HTMLParser().unescape('a=1&b=2') 'a=1&b=2'到 python3.4 之后的版本,在 html 模块新增了 unescape 方法。# python3.4 >>> import html >>> html.unescape('a=1&b=2') 'a=1&b=2'推荐最后一种写法,因为 HTMLParser.unescape 方法在 Python3.4 就已经被废弃掉不推荐使用,意味着之后的版本有可能会被彻底移除。另外,sax 模块也有支持反转义的函数>>> from xml.sax.saxutils import unescape >>> unescape('a=1&b=2') 'a=1&b=2'
2020年10月25日
503 阅读
0 评论
0 点赞
2020-09-23
django ImportExportModelAdmin自定义导出数据
官方文档:django-import-exportdjango 导出数据到excel借助官方文档的一些数据进行理解:class Author(models.Model): name = models.CharField(max_length=100) def __str__(self): return self.name class Category(models.Model): name = models.CharField(max_length=100) def __str__(self): return self.name class Book(models.Model): name = models.CharField('Book name', max_length=100) author = models.ForeignKey(Author, blank=True, null=True) author_email = models.EmailField('Author email', max_length=75, blank=True) imported = models.BooleanField(default=False) published = models.DateField('Published', blank=True, null=True) price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True) categories = models.ManyToManyField(Category, blank=True) def __str__(self): return self.name创建导入或导出的资源from import_export import resources from core.models import Book class BookResource(resources.ModelResource): class Meta: model = Book # 要影响哪些模型字段将包含在导入导出的资源中,请使用fields(自定义)选项将字段列入白名单 fields = ('id', 'name', 'price',) # 或将exclude(自定义)字段列入黑名单的选项 exclude = ('imported', ) # export_order(自定义) 选项设置导出字段的显式顺序 export_order = ('id', 'price', 'author', 'name')现在已经创建了一个模型资源,我们可以导出到csv文件>>> from app.admin import BookResource >>> dataset = BookResource().export() >>> print(dataset.csv) id,name,author,author_email,imported,published,price,categories 2,Some book,1,,0,2012-12-05,8.85,1定义ModelResource字段时,可以遵循模型关系,class BookResource(resources.ModelResource): class Meta: model = Book # 注意这里是中间是两个下划线,表示链式调用的模型关系 fields = ('author__name',)定义ModelResource属性时,可以遵循模型关系,from import_export.fields import Field class BookResource(resources.ModelResource): ''' 自定义属性时,attribute所对应的值可以是链式调用,author__name实际得到的就是作者的名字, 但是在查询时记得使用select_related(),以保证在查询时可以将所关联的外键数据一块查出,否则无法使用链式调用, 最下面会有完整的例子说明 ''' author_name = Field(attribute='author__name', column_name='作者名字') class Meta: model = Book # fields = () export_order = ('id', 'price', 'author', 'name','author_name')可以覆盖资源字段以更改其某些选项`from import_export.fields import Field class BookResource(resources.ModelResource): published = Field(attribute='published', column_name='published_date') class Meta: model = Book可以添加目标模型中不存在的其他字段from import_export.fields import Field class BookResource(resources.ModelResource): myfield = Field(column_name='myfield',attribute='组织数据时自定义的名字') class Meta: model = Bookimport_export.fields.Field可用的属性:导出时进行高级数据处理:''' 并非所有数据都可以从对象/模型属性中轻松提取。 为了在导出时将复杂的数据模型转换为(通常更简单)的已处理数据结构,dehydrate_<fieldname>应定义方法: ''' from import_export.fields import Field class BookResource(resources.ModelResource): full_title = Field() class Meta: model = Book def dehydrate_full_title(self, book): return '%s by %s' % (book.name, book.author.name)在这种情况下,导出看起来像这样:>>> from app.admin import BookResource >>> dataset = BookResource().export() >>> print(dataset.csv) full_title,id,name,author,author_email,imported,published,price,categories Some book by 1,2,Some book,1,,0,2012-12-05,8.85,1自定义小部件一个ModelResource创建与给定字段类型的默认控件的字段。如果小部件应使用不同的参数初始化,请设置widgets字典。在此示例窗口小部件中,该published字段被覆盖以使用其他日期格式。此格式将同时用于导入和导出资源。class BookResource(resources.ModelResource): class Meta: model = Book widgets = { 'published': {'format': '%d.%m.%Y'}, }应用场景:视图是这样的:渲染上面的视图主要用到了两个表:观看表和分享表class WatchStatistics(models.Model): """ 观看 """ # 支持匿名用户 user = models.ForeignKey(User, null=True) course = models.ForeignKey(VideoInfo, related_name="watch_course") ip = models.CharField(max_length=31) duration = models.DecimalField(decimal_places=2, max_digits=12, default=0.00, null=True) createDate = models.DateTimeField(auto_now_add=True) enterprise = models.ForeignKey(Enterprise, related_name="watch_enterprise") startDate = models.DateTimeField() endDate = models.DateTimeField() type = models.CharField(max_length=50, choices=USER_TYPE_CHOICES, default=REGISTER_USER) class DistributionRelationship(models.Model): """ 分享 """ # 受邀人 invited_user = models.ForeignKey(User, related_name='invited_user', null=True) # 分享人 share_user = models.ForeignKey(User, related_name='share_user', null=True) course = models.ForeignKey("course.VideoInfo", related_name="relationship_course") createDate = models.DateTimeField(auto_now_add=True) updateDate = models.DateTimeField(auto_now=True)难度就在于把两张表数据糅合在一块,并且还需要一些自定义的列,导出excel后端代码:from import_export import resources from import_export import fields from .models import WatchStatistics class WatchStatisticsResource(resources.ModelResource): # attribute所对应的值,中间是两个下划线,链式调用 title = fields.Field(column_name='课程名称', attribute='course__title') user = fields.Field(column_name='用户', attribute='user__owner__name') tel = fields.Field(column_name='电话号码', attribute='user__owner__tel') view_count = fields.Field(column_name='访问次数', attribute='view_count') total_duration = fields.Field(column_name='累计观看时间(分钟)', attribute='total_view_time') endDate = fields.Field(column_name='最后观看时间', attribute='endDate') # share_user 要对应到group_user.share_user share_user = fields.Field(column_name='分享人', attribute='share_user') class Meta: model = WatchStatistics fields = ( ) export_order = ('title', 'user', 'tel', 'view_count', 'total_duration', 'endDate', 'share_user') widgets = { 'endDate': {'format': '%Y-%m-%d %H:%M:%S'}, } @method_decorator(login_required, name='dispatch') class AdminExport(View): resource_model = None redirect_space = None model_class = None datetime_fields = [] search_fields = [] default_filters = {} prefix = "" default_order_sort_field = ['id'] def export(self, request, queryset): content_type = request.GET.get('content_type', 'application/vnd.ms-excel') dataset = self.resource_model().export(queryset=queryset) filename = "%s_%s" % (self.prefix, utils.datetime2string()) if "excel" in content_type: suffix = "xls" elif "csv" in content_type: suffix = "csv" else: messages.error(request, u'导出格式有误!') logger.info("export format error") return redirect(self.redirect_space) content = getattr(dataset, suffix) # # content_type 这里响应对象获得了一个特殊的mime类型,告诉浏览器这是个excel文件不是html response = HttpResponse(content, content_type=content_type) # # 这里响应对象获得了附加的Content-Disposition协议头,它含有excel文件的名称,文件名随意,当浏览器访问它时,会以"另存为"对话框中使用它. response['Content-Disposition'] = 'attachment; filename=%s' % ( '{}.{}'.format(filename, suffix),) return response class WatchStatisticsExport(AdminExport): resource_model = WatchStatisticsResource redirect_space = 'analysis:time' model_class = WatchStatistics prefix = "watchstatistics" datetime_fields = [] search_fields = [] default_filters = {} def get(self, request): course_id = self.request.GET.get('course_id') start_time = self.request.GET.get('start_time') end_time = self.request.GET.get('end_time') watchstatistics_list = WatchStatistics.objects.filter(course=course_id).select_related().order_by('-endDate') if start_time: watchstatistics_list = watchstatistics_list.filter(endDate__gte=start_time) if end_time: watchstatistics_list = watchstatistics_list.filter(endDate__lte=end_time) # 查询出当前课程的分享表 distribution_list = DistributionRelationship.objects.filter(course=course_id).select_related() invited_user_list = [] base_user = OrderedDict() for watch in watchstatistics_list: user = base_user.setdefault(watch.user_id, []) user.insert(0,watch) # 将分享表里受邀人的id所在记录append for dis in distribution_list: # 将拥有受邀人的id记录在列表,加入多条的话,说明同一直播,此人被不同的人邀请进来或者分享人多次访问会造成多条记录 if dis.invited_user.id == watch.user_id: user.append(dis) invited_user_list.append(watch.user_id) watch_records = [] for user_id, users in base_user.items(): # 判断如果有分享的记录,则excel加入邀请人 if not invited_user_list: group_user = users[0] group_user.view_count = len(users) total_view_time = sum([u.duration for u in users]) group_user.total_view_time = total_view_time watch_records.append(group_user) else: # 判断如果学员与受邀人一致,则分开处理 group_user = users[0] if group_user.user.id in invited_user_list: # 同一个人在同一直播被多人邀请过,查找次数 num = invited_user_list.count(group_user.user.id) # 减去分享记录和访问次数 group_user.view_count = len(users)-num total_view_time = sum([u.duration for u in users[:-num]]) group_user.total_view_time = total_view_time share_user = users[-1].share_user.owner.name group_user.share_user =share_user else: group_user.view_count = len(users) total_view_time = sum([u.duration for u in users]) group_user.total_view_time = total_view_time group_user.share_user = '无' watch_records.append(group_user) return self.export(request, queryset=watch_records)效果如图:
2020年09月23日
778 阅读
0 评论
0 点赞
1
2
3
...
6