2

I am importing contacts from gmail. c_lst is the list that has the names and email address in a dictionary as follows - [{'name': u'fn1 ln1', 'emails': [u'email1@gmail.com']}, {'name': u'fn2 ln2', 'emails': [u'email2@gmail.com']},.

There are two problems with importing contacts:

  1. Some of the contacts that I might be importing, might already be present in the database, in that case, I do not want to add another contact.

  2. Unique usernames. There is a possibility of two emails being same, except the domain names. eg. email@gmail.com and then email@outlook.com in that case, I need to have distinct usernames so the first username would be like email, and the second one would be email1.

I have implemented both of them, and commented for making things clear. Can there be more pythonic way of doing it?

for contact in c_lst:
email = contact.get('emails')[0]
name = contact.get('name').split(' ')
first_name, last_name = name[0], name[-1]
try:
    # check if there is already a user, with that email address
    # if yes then ignore.
    u = Users.objects.get(email = email)
    print "user exists"
except:
    while True:
        username = email.split('@')[0]
        name, idx = username, 1 
        try:
            # user with current username exists, so add numeral
            Users.objects.get(username = username)
            name = username + str(idx)
        except User.DoesNotExist:
            username = name
            u = User.objects.create(username = username, email = email, first_name = first_name, last_name = last_name)
            u.save()
            break

Please let me know, of any other/better flow/approach.

For generating usernames, one might advice generating random numbers, but its okay for me to go sequentially, as it is only one time activity.

user1629366
  • 1,931
  • 5
  • 20
  • 30
  • I think a better way would be to use e-mail addresses as usernames. [A previous question](http://stackoverflow.com/questions/16638414/set-email-as-username-in-django-1-5) may help. [This one](http://stackoverflow.com/questions/15597188/using-email-as-username-field-in-django-1-5-custom-user-model-results-in-fielder) could be useful too. – Paulo Almeida Jul 24 '13 at 10:54
  • Its a conscious design decision, not to do that. – user1629366 Jul 24 '13 at 11:22
  • @user1629366 Instead of adding `str(idx)` to the username, you can use something like `email_1` or `email-1`, now instead of using a `while` loop you can simply get the number after `_` or `-` and increment it and append it to the username. This will help because say if 1000 users have same username part then your `while` loop will iterate 1000 times, which can be skipped if you use different type to username. – Ashwini Chaudhary Jul 24 '13 at 11:45

1 Answers1

0

The one thing I would like to change is to handle the first except explicitly. Since you are using:

u = Users.objects.get(email=email)  # don't add space before and after "=" in argument

It could raise a MultipleObjectsReturned exception then create an infinite loop in the current except block.

So you should at least change your code to:

# ... your code ...
first_name, last_name = name[0], name[-1]
try:
    u = Users.objects.get(email=email)
except User.DoesNotExist:
    # ... your code ....
except User.MultipleObjectsReturned:
    # handle this case differently ?

Well your might want to handle the second try except block similarly but that's your choice.

Hope this helps.

Hieu Nguyen
  • 8,563
  • 2
  • 36
  • 43
  • if I start with the code which I have, one email corresponds to only one user, hence there is no question of multiple users being returned for the same email. – user1629366 Jul 25 '13 at 10:13
  • well the question is how to do things more pythonic, and with that you should catch the exception that you wanna catch ;) – Hieu Nguyen Jul 25 '13 at 10:57