Django 导入导出在用户 csv 上传之前生成用户名
Django import-export generate username before user csv upload
我需要从 csv 文件为我的应用程序批量生成用户。我的 csv 包含以下字段:
last_name、first_name、电子邮件
为了生成用户名,我有一个我希望在 'dehydrate' 方法中使用的函数。脱水方法仅适用于导出,不适用于导入。
[编辑]
在@sanca-kembang 给出下面的答案后,这就是我最终所做的。下面的示例完美运行(django 1.10.5,python 3.6.0)。
tools.py
from django.contrib.auth.models import User
def generate_username(first_name, last_name):
fname = first_name.lower()
lname = last_name.lower()
prefix = "%s%s" % (fname[0], lname)
username = prefix
i = 2
while User.objects.filter(username = username).exists():
username = "%s%d" % (prefix, i)
i += 1
return username
admin.py
from django.contrib.auth.models import User
from import_export import resources, widgets
from import_export.admin import ImportExportModelAdmin
from .tools import generate_username
class UserResource(resources.ModelResource):
class Meta:
model = User
skip_unchanged = True
report_skipped = True
fields = ('id', 'last_name', 'first_name', 'email', 'username')
def import_obj(self, obj, data, dry_run):
first_name = data.get('first_name')
last_name = data.get('last_name')
username = generate_username(first_name, last_name)
for field in self.get_fields():
if isinstance(field.widget, widgets.ManyToManyWidget):
continue
if field.column_name == 'username':
data.update({'username': username})
print(obj)
self.import_field(field, obj, data)
class UserAdmin(ImportExportModelAdmin):
resource_class = UserResource
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
我查了源码,发现import和export的方法不一样...export_field
的函数有dehydrate_
属性,但是import_field
没有.. .
def export_field(self, field, obj):
field_name = self.get_field_name(field)
method = getattr(self, 'dehydrate_%s' % field_name, None)
if method is not None:
return method(obj)
return field.export(obj)
def import_field(self, field, obj, data):
"""
Calls :meth:`import_export.fields.Field.save` if ``Field.attribute``
and ``Field.column_name`` are found in ``data``.
"""
if field.attribute and field.column_name in data:
field.save(obj, data)
我认为你需要覆盖 import_obj
的功能,你的例子:
from import_export import resources, widgets
from import_export.admin import ImportExportModelAdmin
# your package imported
class UserResource(resources.ModelResource):
class Meta:
model = User
....
def dehydrate_username(self, user):
# your unfinish code got here,
# if you want to enable for export mode...
# username = generate_username_function here
return username
def import_obj(self, obj, data, dry_run):
"""
Traverses every field in this Resource and calls
:meth:`~import_export.resources.Resource.import_field`.
"""
for field in self.get_fields():
if isinstance(field.widget, widgets.ManyToManyWidget):
continue
# find specific `field_name`
# param of `data` is OrderDict
if field.column_name == 'username':
data.update({'username': 'Hello %s' % data.get('username')})
# checkout the changed object
print(obj)
self.import_field(field, obj, data)
这是我的测试...
See also this similiar issue; https://github.com/django-import-export/django-import-export/issues/51
希望对您有所帮助..
我需要从 csv 文件为我的应用程序批量生成用户。我的 csv 包含以下字段:
last_name、first_name、电子邮件
为了生成用户名,我有一个我希望在 'dehydrate' 方法中使用的函数。脱水方法仅适用于导出,不适用于导入。
[编辑] 在@sanca-kembang 给出下面的答案后,这就是我最终所做的。下面的示例完美运行(django 1.10.5,python 3.6.0)。
tools.py
from django.contrib.auth.models import User
def generate_username(first_name, last_name):
fname = first_name.lower()
lname = last_name.lower()
prefix = "%s%s" % (fname[0], lname)
username = prefix
i = 2
while User.objects.filter(username = username).exists():
username = "%s%d" % (prefix, i)
i += 1
return username
admin.py
from django.contrib.auth.models import User
from import_export import resources, widgets
from import_export.admin import ImportExportModelAdmin
from .tools import generate_username
class UserResource(resources.ModelResource):
class Meta:
model = User
skip_unchanged = True
report_skipped = True
fields = ('id', 'last_name', 'first_name', 'email', 'username')
def import_obj(self, obj, data, dry_run):
first_name = data.get('first_name')
last_name = data.get('last_name')
username = generate_username(first_name, last_name)
for field in self.get_fields():
if isinstance(field.widget, widgets.ManyToManyWidget):
continue
if field.column_name == 'username':
data.update({'username': username})
print(obj)
self.import_field(field, obj, data)
class UserAdmin(ImportExportModelAdmin):
resource_class = UserResource
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
我查了源码,发现import和export的方法不一样...export_field
的函数有dehydrate_
属性,但是import_field
没有.. .
def export_field(self, field, obj):
field_name = self.get_field_name(field)
method = getattr(self, 'dehydrate_%s' % field_name, None)
if method is not None:
return method(obj)
return field.export(obj)
def import_field(self, field, obj, data):
"""
Calls :meth:`import_export.fields.Field.save` if ``Field.attribute``
and ``Field.column_name`` are found in ``data``.
"""
if field.attribute and field.column_name in data:
field.save(obj, data)
我认为你需要覆盖 import_obj
的功能,你的例子:
from import_export import resources, widgets
from import_export.admin import ImportExportModelAdmin
# your package imported
class UserResource(resources.ModelResource):
class Meta:
model = User
....
def dehydrate_username(self, user):
# your unfinish code got here,
# if you want to enable for export mode...
# username = generate_username_function here
return username
def import_obj(self, obj, data, dry_run):
"""
Traverses every field in this Resource and calls
:meth:`~import_export.resources.Resource.import_field`.
"""
for field in self.get_fields():
if isinstance(field.widget, widgets.ManyToManyWidget):
continue
# find specific `field_name`
# param of `data` is OrderDict
if field.column_name == 'username':
data.update({'username': 'Hello %s' % data.get('username')})
# checkout the changed object
print(obj)
self.import_field(field, obj, data)
这是我的测试...
See also this similiar issue; https://github.com/django-import-export/django-import-export/issues/51
希望对您有所帮助..