Как создать секцию перекрестной информации из разных таблиц в Django
Я надеюсь, что вопрос ниже задан правильно и соответствует правилам сообщества. Более того, даже если я постарался быть более исчерпывающим, чем это возможно, если необходимы некоторые дополнительные детали, пожалуйста, не стесняйтесь спрашивать о них.
Я разрабатываю веб-сервер по следам Локальной библиотеки от Mozilla Developers
Среди набора данных у меня есть одоранты, рецепторы и взаимодействия, которые они способны осуществлять. Ниже представлены модели:
# Create your models here.
class Odorant(models.Model):
Pubchem_ID = models.IntegerField(primary_key = True)
Name = models.CharField(max_length =50)
IUPAC_Name = models.CharField('IUPAC Name', max_length = 250)
Synonim = models.CharField(max_length = 50)
SMILES = models.CharField(max_length = 100) #NOT NULL by default
Molecular_Formula = models.CharField(max_length = 20)
Molecular_Weight = models.DecimalField(max_digits = 8, decimal_places =4)
Atom_Count = models.IntegerField()
Rotatable_Bonds = models.IntegerField()
Molecular_Refractivity = models.DecimalField(null = True, blank = True, max_digits = 5, decimal_places =3)
Volume = models.DecimalField(max_digits = 6, decimal_places =2)
SASA = models.DecimalField('SASA', max_digits = 6, decimal_places =2)
H_Bond_Donor = models.IntegerField()
H_Bond_Acceptor = models.IntegerField()
Total_Charge = models.IntegerField()
pKa = models.DecimalField('pKa', null = True, blank = True, max_digits = 5, decimal_places =2)
AlogP = models.DecimalField('AlogP', null = True, blank = True, max_digits = 5, decimal_places =2)
Polar_Surface_Area = models.DecimalField(max_digits = 5, decimal_places =2)
Target = models.ManyToManyField('Receptor', null = True, blank = True)
def __str__(self):
return f' {self.Name}'
def get_absolute_url(self):
return reverse('odorant-detail', kwargs={'pk' : self.pk})
class Receptor(models.Model):
RepOdor_ID = models.IntegerField('RepOdor ID', primary_key = True)
Name = models.CharField(max_length = 10)
Former_Name = models.CharField(max_length = 10)
Uniprot_ID = models.CharField(max_length = 10)
Sequence = models.TextField (max_length = 1000)
Ligand = models.ManyToManyField('Odorant', null = True, blank = True)
def __str__(self):
return f'{self.RepOdor_ID},{self.Name}'
def get_absolute_url(self):
return reverse('receptor-detail', kwargs={'pk' : self.pk})
class Target(models.Model):
Pubchem_ID = models.ForeignKey(Odorant, on_delete=models.CASCADE)
RepOdor_ID = models.ForeignKey(Receptor, on_delete=models.CASCADE)
Reference_ID = models.ForeignKey(Publication, on_delete=models.CASCADE)
Odorant = models.CharField(max_length = 50)
Receptor = models.CharField(max_length = 10)
EC50 = models.DecimalField('EC50', null = True, blank = True, max_digits = 6, decimal_places =2)
def __str__(self):
return f'{self.Receptor}, {self.Odorant}'
def get_absolute_url(self):
return reverse('target-detail', kwargs={'pk' : self.pk})
Ниже приведены мои views.py и urls.py:
#views.py
from django.shortcuts import redirect, render
from django.views.generic import TemplateView
from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
from .models import Odorant, Receptor, Target
from django.views import generic
#List view of all the data in the DB
class OdorantListView(generic.ListView):
model = Odorant
paginate_by = 98
class ReceptorListView(generic.ListView):
model = Receptor
paginate_by = 98
class TargetListView(generic.ListView):
model = Target
print(model)
paginate_by = 98
#View for the single entry of the DB
class OdorantDetailView(generic.DetailView):
model = Odorant
class ReceptorDetailView(generic.DetailView):
model = Receptor
class TargetDetailView(generic.DetailView):
model = Target
#urls.py
from django.urls import path
from . import views
from django.conf.urls import include
urlpatterns = [
path('', views.index, name='index'),
path('odorant/', views.OdorantListView.as_view(), name='odorant'),
path('receptor/', views.ReceptorListView.as_view(), name='receptor'),
path('target/', views.TargetListView.as_view(), name='target'),
path('publication/', views.PublicationListView.as_view(), name='publication'),
path('odorant/<int:pk>', views.OdorantDetailView.as_view(), name='odorant-detail'),
path('odorant/<int:pk>', views.TargetListView.as_view(), name='odorant-detail'),
path('receptor/<int:pk>', views.ReceptorDetailView.as_view(), name='receptor-detail'),
path('target/<int:pk>', views.TargetDetailView.as_view(), name='target
Наконец, я отображаю эту информацию таким образом:
<div class="content">
<h1 style="text-align: center;">You are looking to {{ odorant.Name }}</h1>
<br>
<br>
<h3 class="text-muted"> General Information </h3>
<p>Pubchem ID: <strong>{{ odorant.Pubchem_ID }}</strong></p>
<p>IUPAC Name: <strong>{{ odorant.IUPAC_Name }}</strong></p>
</div>
Чтобы дать немного предыстории для лучшего понимания моей работы, различные рецепторы могут взаимодействовать с различными молекулами и наоборот. Все эти взаимодействия собраны в таблице Target.
Я пытаюсь создать новый раздел на странице Odorant, где все рецепторы, способные установить взаимодействие с конкретной выбранной пахучей молекулой, будут представлены в виде кликабельных ссылок. То, что я пытался сделать до сих пор, это использовать функцию фильтра, но это неэффективно, потому что слово, которое должно использоваться в качестве фильтра, должно меняться каждый раз, когда открывается другая страница.
Спасибо за время, потраченное на прочтение моего вопроса и, надеюсь, ответ на него.