1

我需要从 csv 文件为我的应用批量生成用户。我拥有的 csv 包含以下字段:

姓氏、名字、电子邮件

为了生成用户名,我有一个希望在“脱水”方法中使用的函数。脱水方法仅适用于出口,不适用于进口。

[编辑] 在@sanca-kembang 给出下面的答案后,这就是我最终要做的。下面的示例完美运行(django 1.10.5,python 3.6.0)。

工具.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

管理员.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)
4

1 回答 1

3

查了源码,发现import和export的方法不一样……export_fielddehydrate_属性的功能,但不是for import_field……

导出: https ://github.com/django-import-export/django-import-export/blob/master/import_export/resources.py#L590-L595

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)

导入: https ://github.com/django-import-export/django-import-export/blob/master/import_export/resources.py#L315-L321

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)

这是我的测试...

测试导入导出

另见这个类似的问题;https://github.com/django-import-export/django-import-export/issues/51

希望有帮助。。

于 2017-01-31T18:50:39.863 回答