Я пишу научное веб-приложение в Django, посвященное аминокислотным последовательностям антител Fab-фрагментов, каждый из которых состоит из одной тяжелой цепи и одной легкой цепи. Каждая из этих цепей состоит из последовательности аминокислотных остатков.Для модели Django требуется одно из двух связанных полей: следует ли использовать oneToOneField?
- Fab 1
- легкой цепи
- остаток 1
- остаток 2
- ...
- тяжелой цепи
- остаток 1
- остаток 2
- ...
- легкой цепи
- Fab 2
- и т.д ...
Мои models.py
по существу это:
from django.db.models import *
class Fab(Model):
name = CharField(max_length=30)
...
def __unicode__(self):
return self.name
class Chain(Model):
fab = ForeignKey(Fab)
TYPE_CHOICES = (
('L', 'light'),
('H', 'heavy'),
)
type = CharField(max_length=5)
...
class Residue(Model):
ch = ForeignKey(Chain)
...
Итак, в процессе ввода Fab в базу данных я создаю 2 цепочки, назначая каждому type
и внешний ключ fab
. Затем, чтобы использовать их в шаблоне, я использую следующее представление, получая каждую цепочку как объект и передавая ее в шаблон независимо от его родительского объекта Fab, что не совсем идеально.
def fab_detail(request, fab_id):
f = get_object_or_404(Fab, pk=fab_id)
h = get_object_or_404(Chain, fab=f, type='H')
l = get_object_or_404(Chain, fab=f, type='L')
return render_to_response('antibodies/fab_detail.html', {
'fab': f,
'light': l,
'heavy': h,
}, context_instance=RequestContext(request))
Однако я хочу:
- есть лучший способ, чтобы обратиться к легкой или тяжелой цепи в шаблоне, например, петля над остатками цепи с
{% for r in fab.light_chain.residue_set.all %}
. - гарантировать, что каждый Fab имеет только 1 легкую цепь и тяжелую цепь 1
Я рассмотрел подклассов Chain
, но не был уверен, как именно достичь подобного результата. Я придумал что-то вдоль линий:
class Chain(Model):
# same as before, but without the fab ForeignKey field
...
class LightChain(Chain):
pass
class HeavyChain(Chain):
pass
class Fab(Model):
name = CharField(max_length=30)
light_chain = OneToOneField(LightChain)
heavy_chain = OneToOneField(HeavyChain)
...
class Residue(Model):
???
Основная проблема у меня в том, как получить LightChain
и HeavyChain
поля содержат Residue
данные. В частности, с чем заменить ch = ForeignKey(Chain)
в классе Residue?
Будут оценены любые предложения или ссылки.
Другая вещь, которую вы, возможно, захотите сделать, - это не «ch = ForeignKey (Chain)» в классе Residue, а скорее ManyToManyField для Chain. (Я вообще не отвечаю на ваш вопрос, а скорее разделяю идею). У меня может быть совершенно неправильное понимание того, что такое «Residue», но если это кусок молекулы, который можно найти в разных местах (например, в разных Fab), это может иметь смысл. (среди прочего, это позволит вам ответить на вопрос, «в котором Fabs делает это Residue?», если это имеет смысл) – Arthur
Спасибо за это @Arthur. Попытавшись кратко, похоже, что ваше третье решение будет хорошим вариантом для того, что мне нужно сделать, когда я получу все, что работает.Тем не менее, у меня возникли проблемы с доступом к «заводской» обратной связи из объекта Chain. например 'f = Fab (...); l = цепочка(); f.light = l; print l.fab_as_light' вызывает исключение 'DoesNotExist: Fab соответствия запроса '. Есть ли что-то, что мне не хватает в этом рабочем процессе? – jared
Кроме того, с тех пор, как вы его воспитывали, в биологии аминокислота [остаток] (http://en.wikipedia.org/wiki/Residue_%28chemistry%29) является всего лишь строительным блоком, который составляет часть белка. Если белок был представлен поездом, то каждый остаток был бы одним из вагонов поезда. То, что делает один белок отличным от другого, - это последовательность этих остатков. Вы можете быть прав, говоря, что я должен иметь ManyToManyField здесь, но я бы назвал его ResidueTypes. Здесь я использую Residue для обозначения «экземпляра ResidueType в данной позиции в белковой цепочке». – jared