Django Import Export如何过滤关联用户的ForeignKey外键字段
解决方案
1. 修复导入逻辑冗余问题
你当前的simple_upload视图里存在重复导入的逻辑:手动遍历imported_data创建Lead的代码和下方import_data方法执行的导入逻辑重复,且手动创建的Lead完全没有设置organisation字段,先把这段手动遍历保存的代码全部删除。
2. 改造LeadResource支持传入当前用户
修改resources.py,给LeadResource增加初始化参数接收当前登录用户,并重写before_save_instance方法自动填充organisation字段:
from import_export import resources, fields from .models import Lead class LeadResource(resources.ModelResource): nome = fields.Field(attribute='nome', column_name='nome') luogo = fields.Field(attribute='luogo', column_name='regione') class Meta: model = Lead report_skipped = True # 排除不需要从Excel读取的organisation字段 exclude = ('organisation',) def __init__(self, user, *args, **kwargs): self.user = user super().__init__(*args, **kwargs) def before_save_instance(self, instance, using_transactions, dry_run): # 自动给导入的线索绑定当前用户的UserProfile instance.organisation = self.user.userprofile super().before_save_instance(instance, using_transactions, dry_run)
3. 改造上传视图传入当前用户
修改views.py,给视图增加登录校验,实例化LeadResource时传入当前登录用户:
from django.contrib.auth.decorators import login_required from django.shortcuts import render from tablib import Dataset from .resources import LeadResource @login_required # 强制用户登录才能使用导入功能 def simple_upload(request): if request.method == 'POST': # 传入当前登录用户初始化Resource Lead_resource = LeadResource(request.user) dataset = Dataset() newdoc = request.FILES['myfile'] imported_data = dataset.load(newdoc.read(), format='xlsx') result = Lead_resource.import_data(imported_data, dry_run=True) # 测试导入 if not result.has_errors(): Lead_resource.import_data(imported_data, dry_run=False) # 正式导入 return render(request, 'input.html')
4. (可选)Admin后台导入也自动填充organisation
如果需要后台导入时也自动绑定当前操作用户的UserProfile,修改admin.py:
from django.contrib import admin from import_export.admin import ImportExportModelAdmin from .models import Lead @admin.register(Lead) class PersonAdmin(ImportExportModelAdmin): readonly_fields = ('date_added',) def get_resource_kwargs(self, request, *args, **kwargs): # 给Resource传入当前登录的admin用户 rk = super().get_resource_kwargs(request, *args, **kwargs) rk['user'] = request.user return rk
注意事项
- 确保每个
User实例都有对应的UserProfile关联对象,避免赋值organisation时报错,可以通过Django信号在创建User时自动创建关联的UserProfile。 - 你之前做的
organisation字段过滤逻辑可以正常生效,因为导入的所有线索都已经绑定了对应用户的UserProfile,天然满足仅本人可见的要求。
内容的提问来源于stack exchange,提问作者Gianmaria Di Fronzo
相关产品推荐
相关产品推荐

