问题描述
在创建实例时尝试分配add_by用户并希望创建另一个引用当前实例的模型实例
Trying to assign added_by user while creating an instance and want to create another model instance referring to the current instance
views.py
class ImportFarmersView(APIView):
parser_classes = (MultiPartParser,)
def post(self,request,org_slug=None,format=None,*args,**kwargs):
serializer=TmpFileUploadSerializer(data=request.data)
if not serializer.is_valid():
return Response(data=serializer.errors,status=status.HTTP_400_BAD_REQUEST)
entries=serializer.validated_data['file']
profile_resource=ProfileResource()
dataset=Dataset()
imported_data = dataset.load(open(entries.temporary_file_path(),'rb').read(),'xls')
result = profile_resource.import_data(dataset, dry_run=True) # Test the data import
if result.has_errors():
return Response(status=status.HTTP_406_NOT_ACCEPTABLE)
profile_resource.import_data(dataset, dry_run=False) # Actually import now
return Response(status=status.HTTP_202_ACCEPTED)
resources.py
resources.py
class ProfileResource(resources.ModelResource):
created_at=fields.Field(readonly=True)
updated_at=fields.Field(readonly=True)
class Meta:
model=Profile
skip_unchange=True
report_skipped=False
import_id_fields=('slug','email')
预先感谢
推荐答案
我使用了@Jagu提出的before_import_row
答案的替代解决方案.
I used an alternate solution to the before_import_row
answer proposed by @Jagu.
我不想使用before_import_row
解决方案的原因是因为它迫使我为资源创建字段属性.另外,在管理页面中的导入过程中,我的用户可能会与导入程序说的This importer will import the following fields: field1, field2, autofield1, autofield2
要求的字段混淆.相反,我希望它说:This importer will import the following fields: field1, field2
.
The reason why I did not want to use the before_import_row
solution is because it forces me to create a field attribute for the resource. In addition, during the import process in the admin page, my users will potentially be confused with the fields that are required by the importer when it says: This importer will import the following fields: field1, field2, autofield1, autofield2
. Instead I would rather prefer it to say: This importer will import the following fields: field1, field2
.
让我们继续解决问题.
假设我有这个模型:
class LotNumber(models.Model):
lot_number = models.CharField(
max_length=16,
primary_key=True
)
is_active = models.BooleanField(
default=True
)
created_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
null=True,
blank=True,
editable=False,
related_name='+',
on_delete=models.SET_NULL
)
我将created_by
属性指定为自动填充字段.
现在这是我的资源类的样子:
Now here's what my resource class looks like:
class LotNumberResource(resources.ModelResource):
class Meta:
model = LotNumber
skip_unchanged = True
report_skipped = False
fields = (
'lot_number',
'is_active',
)
def after_import_instance(self, instance, new, **kwargs):
instance.created_by = kwargs['user']
如您所见,在我的Meta
块中,我只需要指定lot_number
和is_active
.但是,我选择覆盖的方法是after_import_instance
.最初,我尝试使用before_import_row
,但是修改行并没有自动填充created_by
字段.深入研究源代码后,我注意到方法get_or_init_instance
在before_import_row
方法之后被调用(请参阅源代码此处),它使用我定义的资源类来获取模型实例(请参见源代码此处).因此,如果资源类未在fields
属性中列出自动填充的字段,则实例将永远不会获取该字段.
As you can see, in my Meta
block, I only have to specify lot_number
and is_active
. However, what method I chose to override is after_import_instance
. At first I tried to use before_import_row
but modifying the row did not auto-populate the created_by
field. After digging into the source code, I noticed that that the method get_or_init_instance
is called after the before_import_row
method (see source code here), which fetches the model instance using my defined resource class (see source code here). Therefore, if the resource class did not list the auto-populated field in the fields
attribute, the instance would never fetch that field.
这篇关于django-import-export分配当前用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!