对于研究蝙蝠(http://www.dbchiro.org)的自然数据的Web应用程序,我需要能够提出一个视图,允许将文件从电子表格(csv,ods文件,xls)导入数据库。要将此数据导入单个表,没问题,存在多个扩展(特别是django-import-export或django-csvimport)。另一方面,我的需求更加特殊,因为我的自然主义数据分布在几个不同的表中(不包括字典表)。
这是示意图:
我想得到的是能够使用单个csv文件导入会话数据,该文件将填充最后两个模型:观察(瞄准)和每个观察(观察到的每个物种),其详细数据( CountDetail)。
是否有一个或多个简单的解决方案(我做得很好,但我也不是一个优秀的python专家)。
否则,我想象的解决方案是加载此csv数据(在特定模型中?)并为每次导入执行查询以填充模型:
我正在接受建议/示例/片段:)
谢谢!
佛瑞德。
class Place(models.Model):
id_place = models.AutoField(primary_key=True, db_index=True)
[...]
class Meta:
verbose_name = "Localité"
unique_together = ['name', 'municipality', 'type']
class Session(models.Model):
id_session = models.AutoField(primary_key=True)
contact = models.ForeignKey(Contact,models.DO_NOTHING, null=True, verbose_name=_("Type de contact"))
place = models.ForeignKey(Place,on_delete=models.CASCADE,verbose_name='Localité associée')
date_start = models.DateField(
verbose_name='Date de début', help_text=_('Format de date: <em>01/01/2017</em>.'))
[...]
timestamp_create = models.DateTimeField(
auto_now_add=True, editable=False)
timestamp_update = models.DateTimeField(
auto_now=True, editable=False)
created_by = models.ForeignKey(
settings.AUTH_USER_MODEL, null=True, db_index=True, editable=False, related_name='session_creator')
updated_by = models.ForeignKey(
settings.AUTH_USER_MODEL, null=True, db_index=True, editable=False, related_name='session_modifier')
def __str__(self):
return "%s ∙ %s ∙ %s" % (
self.place, datetime.date(self.date_start.year, self.date_start.month, self.date_start.day), self.contact)
class Meta:
verbose_name = "Session d'inventaire/observations"
unique_together = ["place", "contact", "date_start"]
class Sighting(models.Model):
id_sighting = models.AutoField(_('id unique'), primary_key=True)
session = models.ForeignKey(
Session, on_delete=models.CASCADE, verbose_name=_('Session associée'))
period = models.CharField(max_length=50, blank=True, null=True, verbose_name=_('Période d\'observation'))
codesp = models.ForeignKey(
Specie, on_delete=DO_NOTHING, verbose_name=_('Espèce ou groupe d\'espèce'))
total_count = models.PositiveIntegerField('Nombre total', blank=True, null=True, help_text=_('Désactivé pour les données acoustiques et en main'))
breed_colo = models.NullBooleanField(
verbose_name='Colonie de reproduction')
[...]
timestamp_create = models.DateTimeField(
auto_now_add=True, editable=False)
timestamp_update = models.DateTimeField(
auto_now=True, editable=False)
created_by = models.ForeignKey(
settings.AUTH_USER_MODEL, null=True, db_index=True, editable=False, related_name='sighting_creator')
updated_by = models.ForeignKey(
settings.AUTH_USER_MODEL, null=True, db_index=True, editable=False, related_name='sighting_modifier')
def __str__(self):
return "%s ∙ %s ∙ %s" % (self.session, self.codesp, self.total_count)
class Meta:
verbose_name = "Observation"
verbose_name_plural = "Observations"
unique_together = ["codesp", "session"]
class CountDetail(models.Model):
id_countdetail = models.AutoField(primary_key=True)
sighting = models.ForeignKey(Sighting,
on_delete=models.CASCADE, related_name='countdetail_sighting')
method = models.ForeignKey(Method, on_delete=models.DO_NOTHING, verbose_name=_('Méthode'), blank=True,
null=True)
sex = models.ForeignKey(Sex,models.DO_NOTHING,blank=True,null=True,verbose_name=_('Sexe'))
age = models.ForeignKey(Age,models.DO_NOTHING,blank=True,null=True,verbose_name=_('Age estimé'))
[...]
timestamp_create = models.DateTimeField(
auto_now_add=True, editable=False)
timestamp_update = models.DateTimeField(
auto_now=True, editable=False)
created_by = models.ForeignKey(
settings.AUTH_USER_MODEL, null=True, db_index=True, editable=False, related_name='countdetail_creator')
updated_by = models.ForeignKey(
settings.AUTH_USER_MODEL, null=True, db_index=True, editable=False, related_name='countdetail_modifier')
def __str__(self):
return "%s ∙ %s ∙ %s ∙ %s" % (self.sighting.session.place.name, self.sex, self.age, self.count)
class Meta:
verbose_name = "4 ∙ Comptage détaillé"
答案 0 :(得分:1)
您可以使用django-import-export。
在admin.py中,您可以创建类资源并添加到admin。
admin.py
from .models import Place,Session
from import_export import resources,widgets
from import_export.fields import Field
from django.contrib import admin
class SessionResource(resources.ModelResource):
id_session = Field(column_name='field_id_sesion_excel',attribute='id_session')
place = Field(column_name='place_field_excel', attribute='place', widget=widgets.ForeignKeyWidget(Contact))
class Meta:
model = Session
skip_unchanged = True
def before_import_row(self,row, **kwargs):
value = row['place_field_excel']
obj = Place.objects.create(id_place=value) #create object place
row['place_field_excel'] = obj.id # update value to id ob new object
def save_instance(self,instance, using_transactions=True, dry_run=False):
try:
instance.save() # inside try for ignore error on duplicate primary keys
except:
pass
@admin.register(Session)
class SessionAdmin(ImportExportModelAdmin,admin.ModelAdmin):
resource_class = SessionResource
你可以从csv,xls等导入