Reputation: 11493
For a simple activation key for an account, I have to create the key from random numbers while making sure that I'm not using the same key as another account. Right now, this is what I have:
def get_random_word():
word = ''
i = 0
while i in range(10) and User.objects.filter(activation_key = word).exists():
word += random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789')
i+=1
return word
The problem, I realize now, is that I use django's built in User
class with a user profile like this:
def create_user_info(sender, instance, created, **kwargs):
if created:
UserInfo.objects.create(user=instance)
post_save.connect(create_user_info, sender=User)
class UserInfo(models.Model):
user = models.OneToOneField(User)
pen_name = models.CharField(max_length=30)
activated = models.BooleanField()
activation_key = models.CharField(max_length=40)
def __unicode__(self):
return self.email + '-' + self.pen_name
I need to filter by the user profile. So, in short, how do I filter by a key or, more specifically, a user profile.
Upvotes: 1
Views: 3579
Reputation: 2187
You don't even need to add the related_name value to the user relationship. The following query works for your profile model.
User.objects.filter(userinfo__activation_key=word).exists()
Upvotes: 0
Reputation: 6814
First, you don't really care if 2 users have the same activation key. This case is so rare that it can't be a target for any kind of attack.
Second, why not include the username in the activation URL?
This way you are assured to have an unique activation URL for each user.
ex: yourwebsite.com/users/activate/{username}/{activationcode}
.
Third, you can use an UUID instead of random. UUID are granted to be unique (well not exactly but 99.99% of the time). http://docs.python.org/library/uuid.html
Fourth, do you really need to keep the activation code in the profile informations? Why not create an independent activation table, you can even set the primary key to be the activation code. Most of the time, it is better to separate informations that won't be used much from the ones you will use often.
Fifth, You don't really need to query the User table at all. You just need to query the UserProfile table and check if the activation key exists. Then and only then, you can use the OneToOne relation to map to the original user.
Upvotes: 1
Reputation: 13486
I am not 100% sure what exactly you want to achieve, but here are two answers which might be fitting your needs:
Generally
First you need to connect the Django built-in user model with your UserProfile
model. This is done in settings.py
setting the AUTH_PROFILE_MODULE
setting
AUTH_PROFILE_MODULE = 'myapp.UserProfile' # replace `myapp` with your application name
Answer 1
You can get the user profile for a specific user via user.get_profile()
assuming user
is a already existing instance of django.contrib.auth.User
.
Answer 2
You can query your UserProfile
model first by whatever key you want to query for and then map the result set back to your user directly, e.g.:
from myapp.models import UserProfile
profiles = UserProfile.objects.filter(activation_key='abcdef')
for profile in profiles:
print profile.user # this is the profiles connected user instance
Upvotes: 1
Reputation: 2630
first of all, add a related_name to your UserInfo:
class UserInfo(models.Model):
user = models.OneToOneField(User, related_name='profile')
...
https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey.related_name
and then you can do something like this:
User.objects.filter(profile__activation_key=word).exists()
hope it helps :)
Upvotes: 3