如何在Django Web服务器中集成外部Python脚本实现氨基酸序列比对功能
第一步:修复模板文件 BLAST_page.html
你原来的模板多写了一个多余的闭合div,而且同时渲染Django表单对象和手写输入框没必要,另外长序列输入建议用textarea代替单行text输入框,修正后的版本如下:
{% extends "base_generic.html" %} {% block content %} <div class="container-fluid" style="text-align: center;"> <form method="post" action="{% url 'BLAST-process' %}"> {% csrf_token %} <label for="sequence">在下方输入或粘贴你的序列</label><br><br> <textarea id="sequence" class="input_text" name="sequence" style="width:600px; height:200px;">{{ sequence }}</textarea><br><br> <input type="submit" value="提交"> </form> </div> {% endblock %}
第二步:封装BLAST逻辑为可调用函数
你现在的blast.py是独立运行脚本,没法直接接收Django传的参数,把它改成函数形式,返回比对结果而不是直接打印:
from Bio.Blast.Applications import NcbiblastpCommandline from io import StringIO from Bio.Blast import NCBIXML from Bio.Seq import Seq from Bio.SeqRecord import SeqRecord from Bio import SeqIO import numpy as np import os # 替换为你自己的数据库实际路径 DB_PATH = "/Users/santarpia/Documents/tutorial/codorenv/RepOdor/FASTA/db.fasta" # 临时文件存储目录,确保运行Django的用户有该目录的读写权限 TEMP_DIR = "/tmp/blast_temp" os.makedirs(TEMP_DIR, exist_ok=True) def run_blast(sequence): results = [] seq1 = SeqRecord(Seq(sequence), id="query") query_path = os.path.join(TEMP_DIR, "query.fasta") SeqIO.write(seq1, query_path, "fasta") # 运行BLAST比对 output = NcbiblastpCommandline( query=query_path, subject=DB_PATH, outfmt=5 )()[0] blast_result_record = NCBIXML.read(StringIO(output)) # 整理比对结果 for alignment in blast_result_record.alignments: for hsp in alignment.hsps: res = { "title": alignment.title, "length": alignment.length, "e_value": hsp.expect, "gaps": hsp.gaps, "identities": hsp.identities, "positives": hsp.positives, "score": hsp.score, "bits": hsp.bits, "coverage": hsp.align_length, "identity_percent": np.round((hsp.identities / hsp.align_length) * 100, 2), "query_seq": hsp.query, "match_seq": hsp.match, "sbjct_seq": hsp.sbjct } results.append(res) # 清理临时文件 os.remove(query_path) return results
第三步:编写Django视图处理请求
删掉你那个没用的PHP测试脚本,Django有独立的请求处理体系,在你的app的views.py里添加如下代码:
from django.shortcuts import render from .forms import blast from .blast import run_blast # 渲染表单页面的视图 def blast_page(request): form = blast() return render(request, "BLAST_page.html", {"blast": form}) # 处理表单提交的视图 def blast_process(request): if request.method == "POST": # 获取用户提交的序列 sequence = request.POST.get("sequence", "").strip() if sequence: # 调用BLAST函数获取比对结果 blast_results = run_blast(sequence) # 把结果传给结果展示页面,可自行编写blast_result.html模板展示数据 return render(request, "blast_result.html", {"results": blast_results, "sequence": sequence}) # 提交异常时退回表单页 return render(request, "BLAST_page.html", {"error": "请输入有效序列"})
第四步:配置URL路由
在你的app的urls.py里添加对应的路由匹配,和表单中action的url名对应即可:
from django.urls import path from . import views urlpatterns = [ # 表单页面路由,可自行修改访问路径 path("blast/", views.blast_page, name="BLAST-page"), # 处理表单提交的路由 path("blast/process/", views.blast_process, name="BLAST-process"), ]
额外注意事项
- 如果比对耗时较长,建议增加异步处理逻辑,避免请求超时
- 可自行编写blast_result.html模板,遍历results变量把比对结果格式化展示
内容的提问来源于stack exchange,提问作者Giuliano
相关产品推荐
相关产品推荐

