研究背景
随着中医药文化的不断传承与发展,传统中药材的市场需求逐渐增加。然而,随着药材种类繁多、来源复杂、品质参差不齐,如何高效地管理、分析与展示中药材的相关数据,成为现代中药产业面临的重要课题。传统的药材数据管理方式往往依赖手工记录和静态报表,无法满足大规模药材数据的实时分析与决策需求。为了提升药材的质量管理、流通效率以及市场趋势预测,越来越多的中药企业和科研机构开始寻求基于信息技术的解决方案。
在此背景下,基于Python和Django技术开发的药材数据可视化系统成为了一种理想选择。Python作为一种高效、易于使用的编程语言,具有强大的数据处理和分析能力,特别适合与Django框架结合使用,构建功能强大、交互友好的数据可视化系统。通过数据可视化,用户可以直观地查看各类药材的种类、产地、价格、药效等信息,实时进行统计分析,帮助用户做出更加科学的决策。
药材数据可视化系统不仅可以提高药材管理的效率,帮助企业优化供应链管理,还能够为科研人员提供深入的数据分析工具,支持中药的药效研究、市场需求预测等方面的工作。因此,研究和实现基于Python Django的药材数据可视化系统具有重要的实际意义。
研究目标
本研究的目标是设计并实现一个基于Python Django框架的药材数据可视化系统,旨在为药材行业提供一套高效的数据分析与展示平台。该系统的核心功能包括但不限于以下几个方面:
-
药材Top20统计分析:系统将能够展示药材销量或需求量的Top20,帮助用户了解市场需求的热门药材。通过对销售数据的实时分析,用户可以清晰地看到哪些药材在市场中占据主导地位,从而制定相应的采购和销售策略。
-
药材价格可视化:系统将提供药材价格的可视化分析,包括单价、价格波动趋势等信息。用户可以通过图表查看不同药材的价格区间,识别出价格变化的规律,帮助企业在采购和定价策略中做出更加精准的决策。
-
产地占比分析:通过对药材产地数据的分析,系统将显示各类药材的产地占比情况。用户可以直观地了解各产地药材的市场份额,发现不同地区的供应优势与市场潜力。
-
历史价格趋势:系统将展示药材的历史价格趋势,帮助用户分析药材价格的波动规律,从而做出更具前瞻性的采购与定价决策。
-
新闻资讯整合:系统将整合药材行业的相关新闻资讯,及时向用户推送有关药材市场、政策和技术等方面的最新动态,帮助企业跟踪行业趋势,调整运营策略。
-
后台管理功能:通过后台管理模块,系统将允许管理员对药材数据进行全面管理,包括数据的录入、更新、删除等操作,确保数据的准确性与时效性。
通过以上功能的实现,系统能够为药材行业的企业、科研机构和相关从业者提供全面的数据分析和决策支持,提升管理效率,促进市场发展。
技术栈
前端技术
基础:Html+Css+JavaScript+Echarts
后端技术
Django+爬虫+数据清洗与可视化
数据库:MySQL 8.0.26
数据采集实现
# 获取药方清单
def get_yf_list(cpid,totalRows,keyword):
datas = {
'uid': [],
'name': [],
'recipe': [],
'dosage': [],
'excerpt': [],
'indications': [],
'note': [],
'processing':[],
'tcmName': [],
'recipe_pz': [],
}
counts = {}
print(f"系统将分成{totalRows // 100 + 1}页获取药方")
# 去除一些语气词和没有意义的词
del_words = ['的', ' ', '克', '两', 'g', '千克', '钱', '斤','毫升','浸一宿','两钱','各克']
# 除100(每次取100个药方)向下取整然后+1,遍历所有药方清单
for row_i in range(totalRows // 100 + 1):
print(f'开始获取第{row_i+1}页药方')
result=get_yf_fun(cpid,row_i)
for res in result['data']['pageContent']:
if ('克' in res['recipe']) or ('g' in res['recipe']) or('钱' in res['recipe']) or('斤' in res['recipe'])or('两' in res['recipe']):
datas['uid'].append(res['id'])
datas['dosage'].append(res['dosage'])
datas['excerpt'].append(res['excerpt'])
datas['indications'].append(res['indications'])
datas['name'].append(res['name'])
datas['note'].append(res['note'])
datas['processing'].append(res['processing'])
datas['recipe'].append(res['recipe'])
datas['tcmName'].append(res['tcmName'])
# 对药方进行处理
# 去掉标点符号
all_quotes = re.sub(r"[0-9\s+\.\!\/_,$%^*()?;;:-【】+\"\']+|[+------!,;:。?、~@#¥%......&*()]+", "", res['recipe'])
# 结巴分词自动切割,得到每个药方有什么药材
words = jieba.lcut(all_quotes)
words_final = []
# 如果词不在即将去除的内容中,就添加
for word in words:
if word not in del_words and len(word)>1:
words_final.append(word)
counts[word] = counts.get(word, 0) + 1
datas['recipe_pz'].append(words_final)
#把药方药材存到excel
pd_datas=pd.DataFrame(datas)
pd_datas.to_excel(f'./data/{keyword}药方.xlsx',index=None)
print(f"经过排除后,共获取到{len(datas['uid'])}个药方")
视图页面实现
@login_required(login_url='/login/')
def index(request):
return render(request, 'user/login.html')
def Login(request):
if request.method == 'POST':
user_login_form = UserLoginForm(data=request.POST)
if user_login_form.is_valid():
data = user_login_form.cleaned_data
user = authenticate(username=data['username'], password=data['password'])
if user:
login(request, user)
return redirect('system:index')
else:
return HttpResponse("账号或密码输入有误。请重新输入~")
else:
return HttpResponse("账号或密码输入不合法")
elif request.method == "GET":
user_login_form = UserLoginForm()
context = {'form': user_login_form}
return render(request, 'user/login.html', context)
else:
return HttpResponse("请使用GET或POST请求数据")
def Register(request):
if request.method == 'POST':
user_register_form = UserRegisterForm(data=request.POST)
if user_register_form.is_valid():
new_user = user_register_form.save(commit=False)
new_user.set_password(user_register_form.cleaned_data['password1'])
new_user.save()
return redirect("user:login")
else:
return HttpResponse("注册表单输入有误。请重新输入~")
elif request.method == 'GET':
user_login_form = UserLoginForm()
context = {'form': user_login_form}
return render(request, 'user/register.html', context)
else:
return HttpResponse("请使用GET或POST请求数据")
def Logout(request):
logout(request)
return render(request, 'user/login.html')
@login_required(login_url='/login/')
def Delete(request, id):
if request.method == 'POST':
user = User.objects.get(id=id)
if request.user == user:
logout(request)
user.delete()
return redirect('user:login')
else:
return HttpResponse('你没有删除操作的权限。')
else:
return HttpResponse("仅接受post请求。")