我有两个字段,一个是Symbol,另一个是Source。它们具有ManyToMany关系,因为每个符号可以出现在多个Source中,并且每个Source可以具有多个Symbol。符号也是唯一的。到目前为止一切顺利。
现在,我要允许用户批量添加Symbol-> Source映射的CSV。但是,符号可能会在一个或多个CSV中出现两次,我认为这会违反UNIQUE约束。
我当然可以在遍历CSV的每一行时检查该字符是否已在数据库中。但这不会造成大量数据库调用吗?有没有更有效的方法?
class Source(models.Model):
title = models.CharField(max_length=200, unique=True)
author = models.CharField(max_length=200)
offset = models.IntegerField(default=0)
def __str__(self):
return self.title + " by " + self.author
class Meta:
ordering = ('title',)
class Symbol(models.Model):
name = models.CharField(max_length=1, unique=True)
location = models.ManyToManyField(Source, through='CharInSource')
def __str__(self):
return self.name
class Meta:
ordering = ('name',)
class SymbolInSource(models.Model):
source = models.ForeignKey(Source, on_delete=models.CASCADE)
symbol = models.ForeignKey(Symbol, on_delete=models.CASCADE)
page = models.IntegerField()
def __str__(self):
return "p" + str(self.page)
以下是批量上传逻辑:
class BulkUpload(forms.Form):
file = forms.FileField()
source = forms.ModelChoiceField(queryset=Source.objects.all())
def save(self):
file = self.cleaned_data['file']
source = self.cleaned_data['source']
file.seek(0)
to_be_added = []
for line in file.readlines():
data = line.decode('utf-8').split(',')
name = data[0]
if len(name) > 1:
continue # any faulty characters
page = data[1].split('\n')[0]
symbol = Symbol(name=name)
symbol.save()
location = SymbolInSource(source=source, page=page, symbol=symbol)
location.save()
to_be_added.append({
'source': location.source,
'location': location.page,
'symbol': symbol
})
return to_be_added