I am making a small database and these are the following files. The scripts are working. How can I improve my scripts? Are there any places where a problem could occur? I have yet to write tests for this. Let me know if you need further details.
models.py
from django.db import models
from django.contrib import admin
from django.utils import timezone
class ProteinDatabase(models.Model):
name = models.CharField(max_length=15, blank=True, null=False)
oldname = models.CharField(max_length=15, blank=True, null=False)
accession = models.CharField(max_length=25, blank=True, null=False)
year = models.CharField(max_length=5, blank=True, null=False)
fastasequence = models.TextField(blank=True, null=False)
class Meta:
ordering = ('name',)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.name
class ProteinDatabaseAdmin(admin.ModelAdmin):
search_fields = ('name', 'oldname','accession','year')
class Description(models.Model):
name = models.CharField(max_length=7)
description = models.TextField()
class Meta:
ordering = ('name',)
def __str__(self):
return self.name
class UserUploadData(models.Model):
session_key = models.CharField(max_length=40, default=None)
name = models.CharField(max_length=15, blank=True, null=False)
fastasequence = models.TextField(blank=True, null=False)
urls.py
from django.urls import path
from database import views
urlpatterns = [
path('', views.home, name='home'),
path('database/', views.database, name='database'),
path('category_<str:category>', views.category, name='category'),
path('search/', views.search ,name='search'),
path('search/add_cart/', views.add_cart ,name='add_cart'),
path('remove_cart/<int:id>/', views.remove_cart ,name='remove_cart'),
path('clear_session/', views.clear_session ,name='clear_session'),
path('view_cart/', views.view_cart ,name='view_cart'),
path('clear_session_temp_model/', views.clear_session_temp_model ,name='clear_session_temp_model'),
path('temporary_model_remove/<int:id>/', views.temporary_model_remove ,name='temporary_model_remove'),
path('temporary_model/', views.temporary_model ,name='temporary_model'),
path('download_all_sequences/', views.download_all_sequences ,name='download_all_sequences'),
]
views.py
from django.shortcuts import render, redirect
from .models import ProteinDatabase, UserUploadData, Description
from .forms import UserSubmittedSequenceAnalysis
from django.views.decorators.csrf import csrf_exempt
from django.db.models import Q
from django.contrib import messages
from django.http import HttpResponse
from django.conf import settings
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from io import StringIO
from Bio import SeqIO
import re
import textwrap
def home(request):
return render(request, 'database/home.html')
def category(request, category=None):
"""
Filter the database according to the available categories and return the results.
"""
context = {
'proteins': ProteinDatabase.objects.filter(name__istartswith=category),
'descriptions': Description.objects.filter(name__istartswith=category)
}
return render(request, 'database/category_update.html', context)
def database(request):
"""
Filter the database according to the categories prefixes
"""
categories = ProteinDatabase.objects.order_by('name').values_list('name').distinct()
category_prefixes = []
for category in categories:
prefix = category[0][:3]
if prefix not in category_prefixes:
category_prefixes.append(prefix)
context = {
'category_prefixes': category_prefixes,
'descriptions': Description.objects.all()
}
return render(request, 'database/database.html', context)
def search(request):
"""
This will search according to the keywords. It will also filter and return the results
"""
context = {
'proteins': ProteinDatabase.objects.all()
}
if request.method =='POST':
search_term = request.POST['search_term']
search_term = search_term.strip()
searches = re.split(':|, ?|\s |\- |_ |. |; |\*|\n', search_term)
q_objects = Q()
for search in searches:
q_objects.add(Q(name__icontains=search), Q.OR)
proteins = ProteinDatabase.objects.filter(q_objects)
if proteins:
return render(request,'database/search_results.html', {'proteins' : proteins} )
return render(request,'database/search_page.html')
def add_cart(request):
'''
This will add the proteins to the cart.
'''
if request.method == 'POST':
selected_values = request.POST.getlist('name', []) # qs=param1=1¶m1=3
previously_selected_values = request.session.get('list_names', []) # session is a dict that has a list for the key list_names
previously_selected_values.extend(selected_values)
request.session['list_names'] = previously_selected_values
profile_length = len(selected_values)
message_profile = "Selected {} proteins added to the cart".format(profile_length)
messages.success(request, message_profile)
return redirect("search")
def clear_session(request):
"""
This will clear the session.
"""
session_key = list(request.session.keys())
for key in session_key:
del request.session[key]
return redirect("view_cart")
def remove_cart(request, id):
'''
This will remove the profiles one by one from the cart
'''
protein = ProteinDatabase.objects.get(id=id)
selected_values = request.session.get('list_names')
selected_values.remove(protein.name)
request.session.modified = True
if not selected_values:
message_profile = "Please add sequences to the cart"
messages.success(request, message_profile)
return redirect("search")
else:
return redirect("view_cart")
def view_cart(request):
'''
This will show the cart page with list of profiles
'''
selected_values = request.session.get('list_names')
userdata = UserUploadData.objects.filter(session_key=request.session.session_key)
context = {
'proteins': ProteinDatabase.objects.all(),
'selected_groups': selected_values,
'userdata' : userdata
}
return render(request, 'database/search_user_data.html', context)
def clear_session_temp_model(request):
UserUploadData.objects.filter(session_key=request.session.session_key).delete()
return redirect("view_cart")
def temporary_model_remove(request, id):
instance = UserUploadData.objects.get(session_key=request.session.session_key, id=id)
instance.delete()
return redirect("view_cart")
def temporary_model(request):
"""
A user will upload a sequence or list of sequences. These sequences has to be stored
temporarily in the sesssion. The html file will have a table where the user can delete/update the sequences.
"""
if request.method =='POST':
file = request.POST['fulltextarea']
if not file:
message_profile = "Please add some sequences"
messages.success(request, message_profile)
return redirect("view_cart")
content = ContentFile(file)
for rec in SeqIO.parse(content, "fasta"):
name = rec.id
sequence = str(rec.seq)
UserUploadData.objects.create(session_key=request.session.session_key, name=name, fastasequence=sequence)
message_profile = "Added the sequence"
messages.success(request, message_profile)
return redirect("view_cart")
@csrf_exempt
def download_all_sequences(request):
selected_values = request.session.get('list_names', [])
userdata = UserUploadData.objects.filter(session_key=request.session.session_key)
if not selected_values and not userdata.exists():
message_profile = "Please add sequences to the cart"
messages.success(request, message_profile)
return redirect("view_cart")
else:
file = StringIO()
data = ProteinDatabase.objects.filter(name__in=selected_values)
for item in data:
fasta = textwrap.fill(item.fastasequence, 80)
str_to_write = f">{item.name}\n{fasta}\n"
file.write(str_to_write)
for record in userdata:
fasta = textwrap.fill(record.fastasequence, 80)
str_to_write = f">{record.name}\n{fasta}\n"
file.write(str_to_write)
response = HttpResponse(file.getvalue(), content_type="text/plain")
response['Content-Disposition'] = 'attachment;filename=data_fasta.txt'
response['Content-Length'] = file.tell()
return response