如何在Django中部署Tanimoto相似度计算函数并实现用户交互
问题描述
我有一段计算分子样本与数据库Tanimoto相似度的Python脚本:
from openbabel import pybel def get_similar(targetmol): results = [] # 计算样本分子指纹 targetfp = targetmol.calcfp() for mol in pybel.readfile("smi", "/path/to/db.smi"): # 计算数据库分子指纹 fp = mol.calcfp() # 通过"|"运算符计算Tanimoto指数 tan = fp | targetfp if tan[0] >= 0.8: results.append(tan) return results targetmol = next(pybel.readfile("smi", "/path/to/sample.smi")) print(get_similar(targetmol))
我想把这个函数加到Django开发的网站里,实现用户提交自己的分子后,点击触发计算,在新页面显示数据库中最相似的分子列表。核心困惑是不知道怎么在Django框架里部署这个函数:
- 如何注册函数
- 如何实现点击调用
- 怎么修改代码替代本地的
sample.smi
系统环境:
NAME="Ubuntu" VERSION="20.04.4 LTS (Focal Fossa)" Django==3.1.13 django-admin==2.0.1 openbabel-wheel==3.1.1.7
分步实现指南
1. 项目结构准备
假设你的Django项目名为mol_sim,先新建一个名为similarity的应用:
python manage.py startapp similarity
将similarity添加到项目settings.py的INSTALLED_APPS中:
INSTALLED_APPS = [ ... 'similarity', ]
2. 编写视图函数(处理提交与计算逻辑)
修改similarity/views.py,替换原脚本的本地文件读取逻辑,直接处理用户输入:
from django.shortcuts import render, redirect from openbabel import pybel def get_similar(target_smi): results = [] # 替换为你的数据库文件实际路径,建议用项目根目录相对路径 for mol in pybel.readfile("smi", "./db.smi"): fp = mol.calcfp() # 用用户提交的SMILES直接创建分子对象,替代本地sample.smi读取 target_mol = pybel.readstring("smi", target_smi) target_fp = target_mol.calcfp() tan = fp | target_fp if tan[0] >= 0.8: # 存储分子SMILES和相似度,方便前端展示 results.append({ 'smiles': mol.write("smi").strip(), 'tanimoto': tan[0] }) # 按相似度从高到低排序 results.sort(key=lambda x: x['tanimoto'], reverse=True) return results # 显示用户提交页面 def index(request): return render(request, 'similarity/index.html') # 处理提交请求并返回计算结果 def calculate(request): if request.method == 'POST': user_smi = request.POST.get('smiles_input') if not user_smi: return render(request, 'similarity/index.html', {'error': '请输入有效的SMILES字符串'}) try: similar_mols = get_similar(user_smi) return render(request, 'similarity/results.html', {'results': similar_mols}) except Exception as e: return render(request, 'similarity/index.html', {'error': f'计算出错:{str(e)}'}) # GET请求直接跳转回提交页面 return redirect('index')
3. 配置URL路由
在项目根目录的urls.py中添加应用路由:
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('similarity/', include('similarity.urls')), ]
在similarity目录下新建urls.py,定义应用内部路由:
from django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), path('calculate/', views.calculate, name='calculate'), ]
4. 编写前端模板
在similarity目录下新建templates/similarity文件夹,创建两个模板文件:
index.html(用户提交页面)
<!DOCTYPE html> <html> <head> <title>分子相似度计算</title> </head> <body> <h1>输入分子SMILES字符串</h1> {% if error %} <p style="color: red;">{{ error }}</p> {% endif %} <form method="post" action="{% url 'calculate' %}"> {% csrf_token %} <textarea name="smiles_input" rows="3" cols="50" placeholder="例如:CCO"></textarea> <br> <button type="submit">计算相似度</button> </form> </body> </html>
results.html(结果展示页面)
<!DOCTYPE html> <html> <head> <title>相似度计算结果</title> </head> <body> <h1>相似分子列表(相似度≥0.8)</h1> {% if results %} <table border="1"> <tr> <th>分子SMILES</th> <th>Tanimoto相似度</th> </tr> {% for mol in results %} <tr> <td>{{ mol.smiles }}</td> <td>{{ mol.tanimoto|floatformat:3 }}</td> </tr> {% endfor %} </table> {% else %} <p>未找到相似度≥0.8的分子</p> {% endif %} <br> <a href="{% url 'index' %}">返回重新计算</a> </body> </html>
5. 测试运行
- 将你的
db.smi文件放在项目根目录(或视图函数中指定的路径) - 启动Django开发服务器:
python manage.py runserver
- 访问
http://localhost:8000/similarity/,输入SMILES字符串点击计算即可查看结果。
注意事项
- 若数据库文件过大,循环计算会变慢,后续可优化为预计算指纹并存储到数据库,避免重复读取文件
- 可添加更严格的SMILES格式验证,提升用户输入容错性
- 生产环境部署需替换开发服务器,推荐使用Gunicorn+Nginx组合
内容的提问来源于stack exchange,提问作者Giuliano
相关产品推荐
相关产品推荐

