From 1e6da135fe994643b50288c1dbc8ffc2ff6668d7 Mon Sep 17 00:00:00 2001 From: baoliang Date: Tue, 22 Sep 2020 11:48:12 +0800 Subject: [PATCH] add media feature --- dashboard/models.py | 191 ++++++++++++++++-- polls/templates/polls/monitor_statistics.html | 63 ++++-- polls/views/__pycache__/media.cpython-38.pyc | Bin 2128 -> 1704 bytes .../views/__pycache__/monitor.cpython-38.pyc | Bin 654 -> 2458 bytes polls/views/media.py | 31 +-- polls/views/monitor.py | 96 ++++++++- 6 files changed, 324 insertions(+), 57 deletions(-) diff --git a/dashboard/models.py b/dashboard/models.py index 6de5313..e489b0a 100644 --- a/dashboard/models.py +++ b/dashboard/models.py @@ -3,6 +3,8 @@ from django.contrib.auth.models import User from django.db import models # 权限等级 + + class Level(models.Model): id = models.UUIDField('id', primary_key=True, default=uuid.uuid4) name = models.CharField('等级名', max_length=256, null=True, blank=True) @@ -12,6 +14,8 @@ class Level(models.Model): def __str__(self): return self.name + + class Group_type(models.Model): id = models.UUIDField('id', primary_key=True, default=uuid.uuid4) type = models.CharField('矩阵类型', max_length=256, null=True, blank=True) @@ -19,6 +23,8 @@ class Group_type(models.Model): def __str__(self): return self.type # 矩阵 + + class Group(models.Model): GROUP_STATUS_CHOICES = ( ('0', '关闭'), @@ -37,7 +43,8 @@ class Group(models.Model): district = models.CharField('县', max_length=256, null=True, blank=True) town = models.CharField('乡', max_length=256, null=True, blank=True) village = models.CharField('村', max_length=256, null=True, blank=True) - user = models.ForeignKey(User,on_delete=models.CASCADE,blank=True,null=True) + user = models.ForeignKey( + User, on_delete=models.CASCADE, blank=True, null=True) created = models.DateTimeField('创建时间', auto_now_add=True) updated = models.DateTimeField('更新时间', auto_now=True) @@ -46,6 +53,8 @@ class Group(models.Model): return self.name # 矩阵管理员 + + class Group_admin(models.Model): id = models.UUIDField('id', primary_key=True, default=uuid.uuid4) user = models.ForeignKey( @@ -58,6 +67,8 @@ class Group_admin(models.Model): def __str__(self): return self.group.name # 矩阵成员 + + class Group_user(models.Model): id = models.UUIDField('id', primary_key=True, default=uuid.uuid4) user = models.ForeignKey( @@ -71,6 +82,8 @@ class Group_user(models.Model): return self.user.username # 单位类型 + + class Organizationtype(models.Model): id = models.UUIDField('id', primary_key=True, default=uuid.uuid4) organizationtype = models.CharField( @@ -94,8 +107,9 @@ class Organization(models.Model): district = models.CharField('县', max_length=256, null=True, blank=True) town = models.CharField('乡', max_length=256, null=True, blank=True) village = models.CharField('村', max_length=256, null=True, blank=True) - level = models.ForeignKey(Level,on_delete=models.CASCADE,null=True,blank=True) - directly = models.CharField('直属',max_length=256,null=True,blank=True) + level = models.ForeignKey( + Level, on_delete=models.CASCADE, null=True, blank=True) + directly = models.CharField('直属', max_length=256, null=True, blank=True) created = models.DateTimeField('创建时间', auto_now_add=True) updated = models.DateTimeField('更新时间', auto_now=True) @@ -148,8 +162,8 @@ class NewMedia(models.Model): Organization, on_delete=models.CASCADE, null=True, blank=True) status = models.CharField( '状态', max_length=256, null=True, blank=True, choices=NEWMEDIA_STATUS_CHOICES) - attention = models.CharField('关注量',null=True,blank=True,max_length=256) - remark = models.CharField('备注',null=True,blank=True,max_length=2560) + attention = models.CharField('关注量', null=True, blank=True, max_length=256) + remark = models.CharField('备注', null=True, blank=True, max_length=2560) created = models.DateTimeField('创建时间', auto_now_add=True) updated = models.DateTimeField('更新时间', auto_now=True) @@ -157,16 +171,158 @@ class NewMedia(models.Model): abstract = True ordering = ["-created"] + @classmethod + def category_one_count(cls): + t1 = Weixin.objects.exclude( + organization__province='' + ).filter( + organization__cities='', + organization__district='' + ).count() + t2 = Weibo.objects.exclude( + organization__province='' + ).filter( + organization__cities='', + organization__district='' + ).count() + t3 = Toutiao.objects.exclude( + organization__province='' + ).filter( + organization__cities='', + organization__district='' + ).count() + t4 = Douyin.objects.exclude( + organization__province='' + ).filter( + organization__cities='', + organization__district='' + ).count() + t5 = Qita.objects.exclude( + organization__province='' + ).filter( + organization__cities='', + organization__district='' + ).count() + return t1 + t2 + t3 + t4 + t5 + + @classmethod + def category_two_count(cls): + t1 = Weixin.objects.exclude( + organization__province='', + organization__cities='' + ).filter( + organization__district='' + ).count() + t2 = Weibo.objects.exclude( + organization__province='', + organization__cities='' + ).filter( + organization__district='' + ).count() + t3 = Toutiao.objects.exclude( + organization__province='', + organization__cities='' + ).filter( + organization__district='' + ).count() + t4 = Douyin.objects.exclude( + organization__province='', + organization__cities='' + ).filter( + organization__district='' + ).count() + t5 = Qita.objects.exclude( + organization__province='', + organization__cities='' + ).filter( + organization__district='' + ).count() + return t1 + t2 + t3 + t4 + t5 + + @classmethod + def category_three_count(cls): + t1 = Weixin.objects.exclude( + organization__province='', + organization__cities='', + organization__district='' + ).count() + t2 = Weibo.objects.exclude( + organization__province='', + organization__cities='', + organization__district='' + ).count() + t3 = Toutiao.objects.exclude( + organization__province='', + organization__cities='', + organization__district='' + ).count() + t4 = Douyin.objects.exclude( + organization__province='', + organization__cities='', + organization__district='' + ).count() + t5 = Qita.objects.exclude( + organization__province='', + organization__cities='', + organization__district='' + ).count() + return t1 + t2 + t3 + t4 + t5 + + @classmethod + def media_list(cls, organization_id): + weixin = Weixin.objects.filter(organization_id=organization_id) + weibo = Weibo.objects.filter(organization_id=organization_id) + toutiao = Toutiao.objects.filter(organization_id=organization_id) + douyin = Douyin.objects.filter(organization_id=organization_id) + qita = Qita.objects.filter(organization_id=organization_id) + results = [] + for o in weixin: + result = dict() + result['id'] = o.id + result['code'] = o.code + result['alias'] = o.alias + result['type'] = 'weixin' + results.append(result) + for o in weibo: + result = dict() + result['id'] = o.id + result['code'] = o.code + result['alias'] = o.alias + result['type'] = 'weibo' + results.append(result) + for o in toutiao: + result = dict() + result['id'] = o.id + result['code'] = o.code + result['alias'] = o.alias + result['type'] = 'toutiao' + results.append(result) + for o in douyin: + result = dict() + result['id'] = o.id + result['code'] = o.code + result['alias'] = o.alias + result['type'] = 'douyin' + results.append(result) + for o in qita: + result = dict() + result['id'] = o.id + result['code'] = o.code + result['alias'] = o.alias + result['type'] = 'qita' + results.append(result) + return results + + def __str__(self): return self.code + ':' + self.alias + # 微信公众号 class Weixin(NewMedia): weixinid = models.CharField('微信ID', max_length=256, null=True, blank=True) - - # 微信文章采集 class Weixin_data(models.Model): id = models.UUIDField('id', primary_key=True, default=uuid.uuid4) @@ -349,6 +505,8 @@ class Douyin_data(models.Model): def __str__(self): return self.mewnedia.code # 其他新媒体 + + class Qita(NewMedia): type = models.CharField('新媒体类型', max_length=256, null=True, blank=True) name = models.CharField('新媒体名称', max_length=256, null=True, blank=True) @@ -387,7 +545,9 @@ class Area_code_2020(models.Model): def __str__(self): return self.name -#新闻 +# 新闻 + + class News(models.Model): NEWMEDIA_NEWS_CHOICES = ( ('0', '政策依据'), @@ -396,15 +556,16 @@ class News(models.Model): ('3', '监测通报'), ('4', '舆情热点') ) - id = models.UUIDField('id',primary_key=True,default=uuid.uuid4) - type = models.CharField('文章类型',max_length=256,null=True,blank=True,choices=NEWMEDIA_NEWS_CHOICES) - source = models.CharField('文章来源',max_length=256,null=True,blank=True) - title = models.CharField('文章标题',max_length=256,null=True,blank=True) + id = models.UUIDField('id', primary_key=True, default=uuid.uuid4) + type = models.CharField('文章类型', max_length=256, null=True, + blank=True, choices=NEWMEDIA_NEWS_CHOICES) + source = models.CharField('文章来源', max_length=256, null=True, blank=True) + title = models.CharField('文章标题', max_length=256, null=True, blank=True) image = models.FileField( upload_to='news/%Y/%m/%d/', null=True, blank=True) - author = models.CharField('作者',max_length=256,null=True,blank=True) - date = models.DateField('发表日期',null=True,blank=True,max_length=256) - content = models.TextField('内容',null=True,blank=True) + author = models.CharField('作者', max_length=256, null=True, blank=True) + date = models.DateField('发表日期', null=True, blank=True, max_length=256) + content = models.TextField('内容', null=True, blank=True) def __str__(self): return self.title diff --git a/polls/templates/polls/monitor_statistics.html b/polls/templates/polls/monitor_statistics.html index 4b435bc..0c71189 100644 --- a/polls/templates/polls/monitor_statistics.html +++ b/polls/templates/polls/monitor_statistics.html @@ -4,7 +4,10 @@
-
+
+
+
+
@@ -15,17 +18,20 @@ var myChart = echarts.init(document.getElementById('chart1')); var option = { title: { - text: '新媒体占比', - left: 'center' + text: '政务新媒体种类分布', + left: 'center', + subtext: '总数量'+{{total}}, + subtextStyle: { + fontSize: 16, + } }, tooltip: { trigger: 'item', formatter: '{a}
{b} : {c} ({d}%)' }, legend: { - orient: 'vertical', - left: 'left', - data: ['微博', '公众号', '头条号', '抖音', '其它'] + top: '15%', + data: ['微信', '微博', '头条', '抖音', '其它'] }, series: [ { @@ -33,13 +39,7 @@ type: 'pie', radius: '55%', center: ['50%', '60%'], - data: [ - {value: {{wbc}}, name: '微博'}, - {value: {{wxc}}, name: '公众号'}, - {value: {{ttc}}, name: '头条号'}, - {value: {{dyc}}, name: '抖音'}, - {value: {{qtc}}, name: '其它'} - ], + data: {{chart1_data|safe}}, emphasis: { itemStyle: { shadowBlur: 10, @@ -50,5 +50,42 @@ } ]}; myChart.setOption(option); + + var myChart2 = echarts.init(document.getElementById('chart2')); + var option2 = { + title: { + text: '政务新媒体区域分布', + subtext: '省直总数{{total1}},市州总数{{total2}},县区总数{{total3}}', + subtextStyle: { + fontSize: 16, + }, + left: 'center' + }, + tooltip: { + trigger: 'item', + formatter: '{a}
{b} : {c} ({d}%)' + }, + legend: { + top: '15%', + data: ['兰州市', '兰州新区', '嘉峪关市', '金昌市', '白银市', '天水市', '武威市', '张掖市', '平谅市', '酒泉市', '庆阳市', '定西市', '陇南市', '临夏回族自治州','甘南藏族自治州'] + }, + series: [ + { + name: '总量', + type: 'pie', + radius: '50%', + center: ['50%', '70%'], + data: {{chart2_data|safe}}, + emphasis: { + itemStyle: { + shadowBlur: 10, + shadowOffsetX: 0, + shadowColor: 'rgba(0, 0, 0, 0.5)' + } + } + } + ]}; + + myChart2.setOption(option2); {% endblock %} \ No newline at end of file diff --git a/polls/views/__pycache__/media.cpython-38.pyc b/polls/views/__pycache__/media.cpython-38.pyc index 3e7a7f9a87cbbe07f3fd7503033cfd3fd7909ba7..407856a1b9f02d00a078b6effbb37772dce6dff3 100644 GIT binary patch delta 818 zcmY*WO=}cE5S{M%+{tWQO-v$2`~qPRyok5pMH2~Vf+V5@;xgIptgSmUYt4*_63HP7 zf-Jg>Ac{!585DweFh>0kp8K37$=$QqHLIu%^{ChNs=9dnz4Er)d!<}T%vJJFN7Zd+nEFE|JazU%14XX#YGh zsjHEOigPNG5d}-yO^uOT6#7%bDAQYH3h(Hu&WtzYK1q#LbBU;orWP}oD6?KsW;3Tn zr!>EmPtw8VJu%dSNZboj5l224!fHmE9{hwrz(KJPsFG=6?-qqVd0ZEIt5du>yiK|=&dhOc!Vz3V(}{a3XX zxL6dCH0DKv?-C{QEjWk|Io*n2a0sa>LSN{u3?UiUmTs1rlL4;x;s%Cmqi-j58dIu1N*VV zZbFPZOA^BYoP$flFha4fBcdb?qS|2&19({g`Xs#?aAkG(oBHy8d)7X!?kD_mzG#Q} q54&&N#*QHbto$?J?-XYwj9J#;XVJ5yUqMBEuSZqrlu+V1h`#_{Vd(Y% delta 1238 zcmZWp%ZnUE7_aL0%=Gk3HfxL$Vnhtv8%RL(;IatOWF;Um>_)_aIP`SYPI}Uh*{`d8 z&N#vX|%N2dd`x`+Z-1uPXY-`d>}& zje5OG)NgsY{c>&7J4XAPr(Re{Dy>RVZB>(6t40YU%#7Wn-l|i=4PIv!vp*s0be*=m zk~^$2<&DiRmnw#|-sI7HQ95p#M>g*~JF+l=f$J4q`B6&9fbdlqIypP`n%gu0FTvak>6CsB7$?+NFC?ukmz96b!sB}09n zog-I19~z>%PKM^d=+y=$t1J>kE}|-;N%9-0)KRG|lJvQ0;y)kJj!%=yN3`lgjL5^& z?&1i0+iDEkHz7E&OFxG&{l}wyeN%JudiI*{}$)8L#36A zKoq%j!a(qD2JcJj-Ez45XeZJ{(#fPPvO+{bCbfu3Bg`0=PQqCfw2_a@AdZ5(RS{Q< zq>~0wyyR19JaW!M0VK}I%n0l8BPS`-Cd~jzuWujw+rWXZ*JUM|6}*&t-Cw7%1IP6%Hgx0_P*XYU~8(N z2F{klA%wnF28QE^%X4r-p)$3bK{rUF4+0ToDX4gGn2^TQYUf25Vr}Ew#?zxSXq09j zqEx^W%JIR~!jp=sX;1FgT)Obu`IZ0OY9749eFvUVaqK>1Wq~KvDK(@?jjHd-Ejv+) zZ!`@#%qeY74Fi1Kq#FXqSKBUM;{5nS^NRf<>KFay_>P&J{cql8Ka1o1G~;0gfyf{S e^=*QAwW)K{_z#dj{>VD!9i^_WQH{D!sr_H9R7Io! diff --git a/polls/views/__pycache__/monitor.cpython-38.pyc b/polls/views/__pycache__/monitor.cpython-38.pyc index f4516e0a4d9dbcb39a23f87f8c22503a612f9a92..406870f45f83f2a352f83b0cdc73a3b39467cabf 100644 GIT binary patch literal 2458 zcmb_dTaOe)6z=NV^xS7>7m);wPloYfFN1<6#HgTetQR0Ao#>=zs@?6SFFV!MEK7PG zbX_+X5JUqDt~i^35fTY;2_jxdeDXKctMtG=`r?Bz!Bah#Y%3vz*p)u#e5b1Vt2*a& z)q#9IBfxXhwrXlo5Ps)i<5L3g61=_*0t*<~f`fE~xGmbEBk7VO>$0QhilgePlhRX; zrfYG(WT%~so^i5z7O;#Jtl|{ba2jWD7Uyst7jO}m@DMKJ;gzDE!y|aphk~BRkL?pG zo7aI+s34{i)5RvKs7&4C1@o56v`KSruZb;#$!}WJV5$9HKrO>#%G;(@_m~Rmu;o@n zrtJ0tmojNz-~?&-T(o#K`u==$a{-VeEW6u&HH^6{nYM!a(aM%Sc{g9_R;#{sm|H}MK?cMUmoy9SI*tNcxy27 z>{4|63`d(_Ew^u6i!PjqzBu1GbK>sO<<56M!ph^GJD)GZxVvXgBzocv#oOzgz8W37 zS%HA=sE$vJ_nsJ46KHz^J)1z!CD4up+L=JlC(sKU(SUrMvri0Qj1p_9Cgu$m7S9`> z*x8%eKoFSzGYkeV-rex}nj{ERm_coERcIk9^(>LfJxiiW&yuOyvy>2p;$|U~;FaN3 zHVZ9vN@%6RR6B*C4~r|}DinK+r4S{s97+kSgh~Rdq1?w*TM$}Wys9)#t)g~@%b6_A z;nV`c+HurMhv_}SJFm1dA@pq#T3MP8v!HWfHq;KP5S-k--UBzaDv=C(MtkIwYlLo=OHC+Nd1bPT`8FZNr zhXT%osZb3IVJRF6%Q(BDE=X{6<|YFbev0UqE4Od0!YL@bhGR12kYNXAzb86=u4`Vn z*7s`DaU0Glw9+@&+>xe-u&#l!O7PU+tj^wl(I5mf#z@z{~N1mAV zY}+4mJlCQgsreKp_|$6nqtn!};pEOXrVT~_?4GaM^{KIMf^~JZr?*!| zND2s8%B#zx4}o}yq<4lFpf?W zvp156@QKPWOA)gfm_F5|xq1V{VGxvpXmWw)8-!o11a4f|8!`RBhP|OClZZFRMUYjW&>ZxVm3Zg{q3xKm@Z#EXMA zRvoX7LvretZH~F-T%5RGt}H$-PTnEQoExNYbatMV|C`RofyZxy5Kv~&MnoBv`b|_( z4vF_9B}3Y8=gJ)r%e4*vtg>86SR delta 375 zcmYk2y-EZz5XY0vCcAgufgh!(*oG^%xl%+pv9Q=iuDM3oO%O$Qxg?7o1T3@`&h5ln z@F{!%YnxPpm9JpsjKy&i=9iga@@FQ`TaSD=>G!(?>}hm<_DTu)#$?qZNDjg6Xfc$M z62(;fK&GkUr$mY$Y?U+!qbsG2SOdHfvkup9o=vPaHY?iCWV(Z57JCToE|1xSJeQsJ eD;;MT|G!+p2Gl~je_gBQN*~}qSRANF2kZ~T?Mi0= diff --git a/polls/views/media.py b/polls/views/media.py index 11d3e2e..a360fca 100644 --- a/polls/views/media.py +++ b/polls/views/media.py @@ -2,7 +2,7 @@ from django.http import HttpResponse, JsonResponse from django.views.decorators.csrf import csrf_exempt from django.core.paginator import Paginator -from dashboard.models import Weixin, Weibo, Toutiao, Qita +from dashboard.models import NewMedia from polls.decorators import polls_login_required @@ -11,32 +11,9 @@ from polls.decorators import polls_login_required def medias(request): if request.method == 'POST': return HttpResponse(status=405) - category = request.POST.get('category', 'weixin') - if category == 'weixin': - q = Weixin.objects.filter(status=1) - elif category == 'weibo': - q = Weibo.objects.filter(status=1) - elif category == 'toutiao': - q = Toutiao.objects.filter(status=1) - else: - q = Qita.objects.filter(status=1) - results = [] - for o in q: - result = dict() - result['id'] = o.id - result['code'] = o.code - if category == 'weixin': - result['media_id'] = o.weixinid - elif category == 'weibo': - result['media_id'] = o.weixinid - elif category == 'toutiao': - result['media_id'] = o.weixinid - else: - result['media_id'] = o.weixinid - result['alias'] = o.alias - result['thumbnail'] = request.build_absolute_uri(o.image.url) - results.append(result) - return JsonResponse(results, safe=False) + organization_id = request.GET.get('organization_id') + new_medias = NewMedia.media_list(organization_id) + return JsonResponse({'status': 'success', 'message': new_medias}, safe=False) @csrf_exempt diff --git a/polls/views/monitor.py b/polls/views/monitor.py index 3312ef8..0202a3f 100644 --- a/polls/views/monitor.py +++ b/polls/views/monitor.py @@ -1,5 +1,24 @@ from django.shortcuts import render -from dashboard.models import Douyin, Qita, Toutiao, Weibo, Weixin +from dashboard.models import Douyin, NewMedia, Qita, Toutiao, Weibo, Weixin +from django.db.models import Count, Sum + +COMPARTMENTS = { + '620100000000': '兰州市', + '620200000000': '嘉峪关市', + '620300000000': '金昌市', + '620400000000': '白银市', + '620500000000': '天水市', + '620600000000': '武威市', + '620700000000': '张掖市', + '620800000000': '平凉市', + '620900000000': '酒泉市', + '621000000000': '庆阳市', + '621100000000': '定西市', + '621200000000': '陇南市', + '622900000000': '临夏回族自治州', + '623000000000': '甘南藏族自治州', + '620171000000': '兰州新区' +} def monitor_statistics(request): @@ -8,4 +27,77 @@ def monitor_statistics(request): ttc = Toutiao.objects.count() qtc = Qita.objects.count() dyc = Douyin.objects.count() - return render(request, 'polls/monitor_statistics.html', {'wbc': wbc, 'wxc': wxc, 'ttc': ttc, 'dyc': dyc, 'qtc': qtc}) + total = wbc+wxc+ttc+qtc+dyc + + chart1_data = [] + chart1_data.append({'name': '微信', 'value': wxc}) + chart1_data.append({'name': '微博', 'value': wbc}) + chart1_data.append({'name': '头条', 'value': ttc}) + chart1_data.append({'name': '抖音', 'value': dyc}) + chart1_data.append({'name': '其它', 'value': qtc}) + + results = dict() + q = Weixin.objects.values('organization__cities').order_by( + 'organization__cities').annotate(num_media=Count('organization__cities')) + for row in q: + code = row['organization__cities'] + compartment = COMPARTMENTS[code] + if code in results: + nums = results[compartment] + nums.append(row['num_media']) + else: + results[compartment] = [row['num_media']] + + q = Weibo.objects.values('organization__cities').order_by( + 'organization__cities').annotate(num_media=Count('organization__cities')) + for row in q: + code = row['organization__cities'] + compartment = COMPARTMENTS[code] + if compartment in results: + nums = results[compartment] + nums.append(row['num_media']) + else: + results[compartment] = [row['num_media']] + + q = Toutiao.objects.values('organization__cities').order_by( + 'organization__cities').annotate(num_media=Count('organization__cities')) + for row in q: + code = row['organization__cities'] + compartment = COMPARTMENTS[code] + if compartment in results: + nums = results[compartment] + nums.append(row['num_media']) + else: + results[compartment] = [row['num_media']] + + q = Douyin.objects.values('organization__cities').order_by( + 'organization__cities').annotate(num_media=Count('organization__cities')) + for row in q: + code = row['organization__cities'] + compartment = COMPARTMENTS[code] + if compartment in results: + nums = results[compartment] + nums.append(row['num_media']) + else: + results[compartment] = [row['num_media']] + + q = Qita.objects.values('organization__cities').order_by( + 'organization__cities').annotate(num_media=Count('organization__cities')) + for row in q: + code = row['organization__cities'] + compartment = COMPARTMENTS[code] + if compartment in results: + nums = results[compartment] + nums.append(row['num_media']) + else: + results[compartment] = [row['num_media']] + + chart2_data = [] + for k in results: + chart2_data.append({'name': k, 'value': sum(results[k])}) + + total1 = NewMedia.category_one_count() + total2 = NewMedia.category_two_count() + total3 = NewMedia.category_three_count() + + return render(request, 'polls/monitor_statistics.html', {'chart1_data': chart1_data, 'total': total, 'chart2_data': chart2_data, 'total1': total1, 'total2': total2, 'total3': total3})