在Django中填充我的多对多关系

3b6akqbq  于 2023-01-10  发布在  Go
关注(0)|答案(1)|浏览(146)

我是Django和Python的新手,在我的学习项目中有三个模型:
models.py

class Protein(models.Model):
    protein_id = models.CharField(
        max_length=256, null=False, blank=False, db_index=True)
    taxonomy = models.ForeignKey(
        Taxonomy, on_delete=models.DO_NOTHING, null=True, blank=True)
    length = models.IntegerField(null=True, blank=True)
    access = models.IntegerField(null=False, blank=False, default=0)

    def __str__(self):
        return self.protein_id

class Pfam(models.Model):
    domain_id = models.CharField(
        max_length=256, null=False, blank=False, db_index=True)
    domain_description = models.CharField(
        max_length=256, null=True, blank=True)

    def __str__(self):
        return self.domain_id

class Domain(models.Model):
    pfam = models.ForeignKey(Pfam, on_delete=models.CASCADE)
    description = models.CharField(max_length=256, null=True, blank=True)
    start = models.IntegerField(null=True, blank=True)
    stop = models.IntegerField(null=True, blank=True)
    protein = models.ManyToManyField(
        Protein, related_name='domains', through='ProteinDomainLink')

    def __str__(self):
        return self.pfam.domain_id

class ProteinDomainLink(models.Model):
    protein = models.ForeignKey(Protein, on_delete=models.DO_NOTHING)
    domain = models.ForeignKey(Domain, on_delete=models.DO_NOTHING)

类域具有多对多字段,通过类ProteinDomainLink链接到类Protein。
有三个csv文件可以从中检索数据,我的populate脚本如下所示:
填充_数据. py

data_sequences_file = '../..source_file_1';
pfam_descriptions_file = '../..source_file_2';
data_set_file = '../..source_file_3';

pfam = defaultdict(list)
domains = defaultdict(list)
proteins = defaultdict(list)

... 

with open(pfam_descriptions_file) as pfam_descriptions_csv_file:
    pfam_descriptions_csv_reader = csv.reader(
        pfam_descriptions_csv_file, delimiter=',')
    for row in pfam_descriptions_csv_reader:
        pfam[row[0]]=row[1:2]

with open(data_set_file) as data_set_csv_file:
    data_set_csv_reader = csv.reader(data_set_csv_file, delimiter=',')
    for row in data_set_csv_reader:
        domains[row[5]] = row[4:5]+row[6:8]
        proteins[row[0].strip()] = row[1:2]+row[8:9]

pfam_rows = {}
domain_rows = {}
proteins_rows = {}

...

for domain_id, entry in pfam.items():
    row = Pfam.objects.create(
        domain_id=domain_id,
        domain_description=entry[0]
    )
    row.save()
    pfam_rows[domain_id] = row

for protein_id, entry in proteins.items():
    row, created = Protein.objects.get_or_create(
        protein_id=protein_id,
        taxonomy=taxonomy_rows[entry[0]],
        length=entry[1],
    )
    row.save()
    proteins_rows[protein_id] = row

#That's my question:

for protein_id, domain_id, entry in domains.items():
    row = Domain.objects.create(
        pfam=pfam_rows[domain_id],
        description=entry[1],
        start=entry[2],
        stop=entry[3]
    )
    row.protein.add(proteins_rows[protein_id])
    row.save()

我留下了代码,我可以超越我的问题。我的问题涉及到最后一块,我正在创建域表和添加蛋白质行链接表,在我的情况下,我得到了一个错误:
对于蛋白质ID、域ID,在domains.items()中输入:值错误:没有足够的值来解包(期望3个,得到2个)。
我试着为我的域名使用字典。像这样:

domains = defaultdict(dict)

这样来构建法令:

domains[row[0].strip()][row[5]] = row[4:5]+row[6:8],

但它也不起作用。

3pmvbmvn

3pmvbmvn1#

您所得到的错误与Django ORM无关,它是由于试图将两个值解包成三个变量而引起的:

for protein_id, domain_id, entry in domains.items():

domains.items()(key, list_of_something)对的集合,必须在两个变量中解包,如下所示:

for protein_id, entry in domains.items():

如果需要,可以在嵌套循环中迭代entry列表:

# 'entry' is not a great name here. Using it just for consistency with the original code
for protein_id, entry in domains.items():
    for item in entry:
        <do_something>

相关问题