How to bulk import users

Hi! I need a little help so much…

I try to import some users from a csv file. I’m using the import-export module into the original User model. If I upload the file that I made it imports one user but with blank fields except date_joined, is_staff, is_active, is_superuser . The other fields like username, password, first and last name are empty.
What am I doing wrong?

views.py

from tablib import Dataset
from .resources import UserResource

def simple_upload(request):
    if request.method == 'POST':
        person_resource = UserResource()
        dataset = Dataset()
        new_users = request.FILES['myfile']

        imported_data = dataset.load(new_users.read().decode(), format='csv', headers=False)
        result = person_resource.import_data(dataset, dry_run=True)  # Test the data import

        if not result.has_errors():
            person_resource.import_data(dataset, dry_run=False)  # Actually import now

    return render(request, 'stressz/simple_upload.html')

resources.py

from import_export import resources
from django.contrib.auth.models import User

class UserResource(resources.ModelResource):
    class Meta:
        model = User

I’m using this csv:

Should headers be set to True when creating imported_data?

Also I think you should be using imported_data rather than dataset when calling person_resource.import_data()

Thank you Tim! I tried this code as you suggested if I understood it right, but it resulted to a blank user too:

imported_data = dataset.load(new_users.read().decode(), format='csv', headers=True)
result = person_resource.import_data(imported_data, dry_run=True) 

It might be helpful if you posted the actual file you’re trying to read rather than the image of the data.

Hi Ken! Thank you for the suggestion. Here is the file:

This file doesn’t have a header line, nor do I see anything in your code assigning the columns to fields. Where are you defining how the fields in the CSV get assigned to the model fields?

Sorry, I’m a little bit beginner. :blush: I unfortunately overwrited the file before and uploaded the overwrited one. This is the good link:

I followed the steps of this post where he worked with a model that he created and assigned the fields:

I am using the original User model and I did not know in this case I should define these fields and and how. :sweat_smile:

You’ve got semicolons separating the fields and not commas.

The fields in the CSV are defined by that header row. That’s how the library can figure out which field in each row is to be assigned to a field in the model.

1 Like

Thank you very much Ken and Tim for helping me. It was really semicolons that I don’t know why but now works. :wink:

Nominally, the “c” in csv means “comma”.

However, in your dataset.load statement, you should be able to use the delimiter= parameter to specify what character separates the fields - in this case delimiter=';' (It’s a very useful feature when you’re loading data generated from other sources.

Also, if you’re working with a source of data that doesn’t/can’t provide a header file, see Customize resource options for how to specify what fields are in a file and the order in which they appear.

1 Like

Thank you very much Ken!

Can I have one more question?
I made some changes on my views like the code below. I experience that if just two users in my csv, it imports the users well but if more it works not. The second problem is that every time it makes a blank user. I know this is because my request.POST.get script has a " " part but if it does not have this part it gives me a unique constraint failed message.

def simple_upload(request):
    if request.method == 'POST':

        username = request.POST.get('username', "")
        first_name = request.POST.get('first_name', "")
        last_name = request.POST.get('last_name', "")
        email = request.POST.get('email', "")
        user = User(username=username, first_name=first_name, last_name=last_name, email=email )
        user.save()

        person_resource = UserResource()
        dataset = Dataset()
        new_users = request.FILES['myfile']

        imported_data = dataset.load(new_users.read().decode('utf-8'), format='csv', headers=True)
        result = person_resource.import_data(imported_data, dry_run=True)  # Test the data import

        if not result.has_errors():
            person_resource.import_data(dataset, dry_run=False)  # Actually import now

    return render(request, 'stressz/simple_upload.html')

What happens when there are more than two users?

When the user does not supply the username and/or email, what do you want the system to do? Once you answer that question, you can implement that as logic in an if statement to avoid creating the user in that case. You can also look into using a model form.

Another thing to keep in mind is what do you want to happen when there is a valid duplicate user being sent across? Should it error, update the user or ignore the data in the request?