Django 1.5. Users profile creation - django

I use django 1.5 with custom model MyUser. I want to make users profile page, where he can modify only one field - 'about'.
I tried something like that:
forms.py:
class UserSettingsForm(forms.ModelForm):
class Meta:
model = get_user_model()
fields = ('about')
view.py:
class UserSettings(UpdateView):
form_class = UserSettingsForm
template_name = "user/settings.html"
def get_object(self, queryset=None):
return self.request.user
def get_success_url(self):
return reverse('user_detail', args=[self.request.user.username])
urls:
url(r'^settings/$', UserSettings.as_view(), name='user_settings')
model:
class MyUserManager(BaseUserManager):
def create_user(self, email, password=None):
"""
Creates and saves a User with the given email, date of
birth and password.
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=MyUserManager.normalize_email(email),
# date_of_birth=date_of_birth,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password):
"""
Creates and saves a superuser with the given email, date of
birth and password.
"""
user = self.create_user(email,
password=password,
#date_of_birth=date_of_birth
)
user.is_admin = True
user.save(using=self._db)
return user
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
db_index=True,
)
last_name=models.CharField(max_length=30)
first_name=models.CharField(max_length=30)
about=models.TextField(blank=True)
objects = MyUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['last_name','first_name','about']
def get_full_name(self):
# The user is identified by their email address
return self.email
def get_short_name(self):
# The user is identified by their email address
return self.email
def __unicode__(self):
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
#property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
But I got error: django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'app.MyUser' that has not been installed
How can I make users profile in django 1.5? Thx!

MyUser class should be under the application named 'app' in your settings file in order for the auth framework to pick it.

Related

One To One relationship in Django

I need to make a profile for each user with address and city, and more... with OneToOne relationship in Django models, So I don't know how I can do it, I want to inheritance class Profile from Class User.
and I'v got this error :
django.core.exceptions.FieldError: Unknown field(s) (address) specified for User
this is my model:
#models.py
from django.db import models
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser
)
from phonenumber_field.modelfields import PhoneNumberField
class UserManager(BaseUserManager):
def create_user(self, email, fav_color, lastname, password=None, is_active=True, is_staff=False, is_admin=False,):
"""
Creates and saves a User with the given email and password.
"""
if not email:
raise ValueError('Users must have an email address')
# if not phone_number:
# raise ValueError('user must have phone number')
user = self.model(
email=self.normalize_email(email),
fav_color=fav_color,
lastname=lastname,
city=profile.city,
address=profile.address,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_staffuser(self, email, password):
"""
Creates and saves a staff user with the given email and password.
"""
user = self.create_user(
email,
password=password,
)
user.staff = True
user.save(using=self._db)
return user
def create_superuser(self, email, password, fav_color, lastname,):
"""
Creates and saves a superuser with the given email and password.
"""
user = self.create_user(
email,
password=password,
fav_color=fav_color,
lastname=lastname,
)
user.staff = True
user.admin = True
user.save(using=self._db)
return user
class User(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address', max_length=255, unique=True)
lastname = models.CharField(max_length=100)
fav_color = models.CharField(max_length=10)
active = models.BooleanField(default=True)
staff = models.BooleanField(default=False) # a admin user; non super-user
admin = models.BooleanField(default=False) # a superuser
# notice the absence of a "Password field", that is built in.
objects = UserManager()
USERNAME_FIELD = 'email'
# Email & Password are required by default.
REQUIRED_FIELDS = ['fav_color', 'lastname',]
def get_full_name(self):
# The user is identified by their email address
return self.email
def get_short_name(self):
# The user is identified by their email address
return self.email
def __str__(self): # __unicode__ on Python 2
return self.email
def has_perm(self, perm, obj=None):
"Does the user have specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permission to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
#property
def is_staff(self):
"Is the user a member of staff?"
return self.staff
#property
def is_admin(self):
"Is the user an admin member?"
return self.admin
#property
def is_active(self):
"Is the user active?"
return self.active
class profile(User):
user = models.OneToOneField(User, on_delete=models.CASCADE),
address = models.CharField(max_length=255),
city = models.CharField(max_length=120),
actually i don't know how can i use OneToOne models , and how can i inheritance from base class to order classes
please help , tank you .
You can not use Django model like that. User(AbstractBaseUser) is right because AbstractBaseUser is abstract. There're 2 options
Not recommended, add more fields (city, address...) to User.
Define class Profile(models.Model) as you did, create a profile once User was created.
How?
Assuming you have an accounts app that contains Profile model.
file accounts/models.py, define profile field as you did
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
address = models.CharField(max_length=255)
city = models.CharField(max_length=120)
file accounts/__init__.py, define app configuration will be used.
default_app_config = "accounts.apps.Config"
file accounts/apps.py
from django.apps import AppConfig
class Config(AppConfig):
name = 'accounts'
def ready(self):
from . import signals
file accounts/signals.py, install signals
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver, Signal
from accounts.models import Profile
#receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_related_handler(sender, instance, created, **kwargs):
"""
Once a new User instance was saved:
Check User instance, if this is new instance (created is True)
then create a Profile for this user.
"""
if not created:
return
default_data = dict(city='', address='')
instance.profile = Profile.objects.create(user=instance, **default_data)
Don't forget to add accounts to your INSTALLED_APPS config.

customising django user model is failing

**Hi
I am trying to customize the django default user. Applying migrations works fine. However I get an error when i try to create a super user. Can you please advise why I get this error?
******************** self.UserModel._default_manager.db_manager(database).create_superuser(**user_data)
File "/home/gravityns/PycharmProjects/dev/shop/models.py", line 54, in create_superuser
user.is_staff = True
AttributeError: can't set attribute
# accounts.models.py
from django.db import models
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser
)
from django.core.validators import RegexValidator
class UserManager(BaseUserManager):
def create_user(self, username, password, email):
"""
Creates and saves a User with the given email and password.
"""
if not username:
raise ValueError('Users must have a username')
if not email:
raise ValueError('Users must have an email address')
user = self.model(
username = username,
email = self.normalize_email(email),
)
user.set_password(password)
user.save(using=self._db)
return user
def create_staffuser(self, username, password, email):
"""
Creates and saves a staff user with the given email and password.
"""
user = self.create_user(
username,
email,
password,
)
user.is_staff = True
user.save(using=self._db)
return user
def create_superuser(self, username, password, email):
"""
Creates and saves a superuser with the given email and password.
"""
user = self.create_user(
username,
email,
password
)
user.is_staff = True
user.is_admin = True
user.save(using=self._db)
return user
USERNAME_REGEX = '^[a-zA-Z0-9.#+-]*$'
class User(AbstractBaseUser):
username = models.CharField(max_length=255, validators=[
RegexValidator(regex= USERNAME_REGEX,
message = 'Username must be Alphanumeric or any of the following: ". # + -"')],
unique=True
)
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
created_at = models.DateField(auto_now_add=True, blank=True)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False) # a admin user; non super-user
# notice the absence of a "Password field", that's built in.
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email'] # Email & Password are required by default.
objects = UserManager()
def get_full_name(self):
# The user is identified by their email address
return self.email
def get_short_name(self):
# The user is identified by their email address
return self.email
def __str__(self): # __unicode__ on Python 2
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
#property
def is_staff(self):
"Is the user a member of staff?"
return self.is_staff
#property
def is_admin(self):
"Is the user a admin member?"
return self.is_admin
#property
def is_active(self):
"Is the user active?"
return self.is_active
You're overwriting the normal is_staff attribute with your custom property. You need to rename those properties so that they don't clash with the stuff AbstractBaseUser already implements. Look at how that class implements is_staff and others etc here: https://github.com/django/django/blob/master/django/contrib/auth/models.py#L288
You have a field on User model as User.is_staff and a #property with the same name. So you can't set the property of the model object by user_instance.is_staff = True.
You can have is_staff as a field or as a class property, not both.
You have unncessarily defined properties for is_staff, is_active and is_superuser. But those are already fields, with the exact same name. Therefore, when you try and set user.is_staff = True, Python access your property, and tries to "set" that, rather than the field.
There is no reason to do this. The only reason you would need to define those properties is if you want to disallow setting the fields themselves. But you don't want to do that. (Alternatively, if you didn't want fields at all, but wanted to base the value on some custom logic - but, again, you wouldn't be able to set them unless you defined a custom setter.)
Remove all three of those properties.

post_save signal with sender AUTH_USER_MODEL fires at login

What was done
I have a custom User model called MyUser as it is described in an full example for an custom user model on the docs and a so called UserProfile that is connected to MyUser by an One-to-one relationship like it's described in the Django documentation about how to extend an existing user model.
In the documentation for Customizing authentication is an example for how to connect a post_save signal with the existing User model.
By following this, I put an testing receiver in a signals.py that is loaded by my apps.py file, like it's described in this SO answer.
Configuration
signal.py
def post_save_receiver(sender, instance, created, **kwargs):
send_mail('Testing', "Just testing...", 'hell#earth.tld', ['admin#heaven.tld'], fail_silently=False)
post_save.connect(post_save_receiver, sender=settings.AUTH_USER_MODEL)
models.py
class MyUserManager(BaseUserManager):
def create_user(self, email, password=None):
"""
Creates and saves a User with the given email and password.
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email),
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password):
"""
Creates and saves a superuser with the given email and password.
"""
user = self.create_user(email,
password=password,
)
user.is_admin = True
user.save(using=self._db)
return user
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = MyUserManager()
USERNAME_FIELD = 'email'
def get_full_name(self):
# The user is identified by their email address
return self.email
def get_short_name(self):
# The user is identified by their email address
return self.email
def __str__(self): # __unicode__ on Python 2
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
#property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
views.py
def UserLogin(request):
if request.user.is_authenticated():
return HttpResponseRedirect("http://www.heaven.tld/account")
else:
if request.method == 'POST':
form = UserLoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username, password=password)
if user is not None and user.is_active:
login(request, user)
return HttpResponseRedirect("http://www.heaven.tld/account")
else:
error_msg = 'Please try again!'
return render(request, "development",
{'form':form,
'error_msg':error_msg,
})
else:
error_msg = "Please try again!"
return render(request, "development",
{'form':form,
'error_msg':error_msg,
})
else:
form = UserLoginForm()
return render(request, "development", {'form': form})
The Problem
Now if I log in I always get this mail, but I want it only if a user was created.
Logging in causes the last_login timestamp to be updated, which triggers a save.
As others have stated, you just need to use the created parameter, which your signal receives but you currently ignore.
try:
def post_save_receiver(sender, instance, created, **kwargs):
if created:
send_mail('Testing', "Just testing...", 'hell#earth.tld', ['admin#heaven.tld'], fail_silently=False)
post_save.connect(post_save_receiver, sender=settings.AUTH_USER_MODEL)
I can't understand what will be saved when you login. You can use ipdb to trace it. By the way, if you set the created condition before send_mail function, the problem should be resolved.
if created:
send_mail(...)

Why is Django giving me: 'first_name' is an invalid keyword argument for this function?

I'm trying to create a custom user profile and have modified the example only slightly
from django.conf import settings
from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
class MyUserManager(BaseUserManager):
def create_user(self, email, password=None, first_name=None, last_name=None):
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=MyUserManager.normalize_email(email),
first_name=first_name,
last_name=last_name,
#date_of_birth=date_of_birth,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password, first_name=None, last_name=None):
user = self.create_user(email,
password=password,
first_name=first_name,
last_name=last_name,
#date_of_birth=date_of_birth
)
user.is_admin = True
user.save(using=self._db)
return user
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
db_index=True,
)
first_name=models.CharField(max_length = 30),
last_name=models.CharField(max_length = 30),
#date_of_birth = models.DateField()
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = MyUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
def get_full_name(self):
# The user is identified by their email address
return self.email
def get_short_name(self):
# The user is identified by their email address
return self.email
def __unicode__(self):
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
#property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
When I try to run syncdb I get the following error:
You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Email address: uou#pce.com
Password:
Password (again):
TypeError: 'first_name' is an invalid keyword argument for this function
I have struggled to debug this because of the limited nature of the error message. I feel I'm making a simple mistake what am I doing wrong?
You are trying to set None (Null) value into first_name and it seems that this property don't allow it.
Try this changes:
class MyUserManager(BaseUserManager):
def create_user(self, email, password=None, first_name='', last_name=''):
In model:
first_name=models.CharField(max_length = 30, blank = True)

Custom user model in admin

i try to create a custom user model for adding some custom fields to a user. i used the in django 1.5 introduced new method based on AbstractBaseUser. Everything (login) works, except for the admin-panel. When logging into the admin-interface, i get the following error:
AttributeError at /admin/
'ShopUser' object has no attribute 'is_superuser'
here's my model:
from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
from django.contrib import auth
class ShopUserManager(BaseUserManager):
def create_user(self, email, password=None):
if not email:
raise ValueError("We need an e-mail here...")
user = self.model(
email = ShopUserManager.normalize_email(email),
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password):
user = self.create_user(
email,
password = password,
)
user.is_admin = True
user.is_staff = True
user.save(using=self._db)
return user
class ShopUser(AbstractBaseUser):
email = models.EmailField(
verbose_name = 'e-mail address',
max_length = 255,
unique = True,
db_index = True,
)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
objects = ShopUserManager()
USERNAME_FIELD = 'email'
# REQUIRED_FIELDS = ['']
def __unicode__(self):
return self.email
def has_perms(self, perm_list, obj=None):
"""
Returns True if the user has each of the specified permissions. If
object is passed, it checks if the user has all required perms for this
object.
"""
for perm in perm_list:
if not self.has_perm(perm, obj):
return False
return True
def has_module_perms(self, app_label):
"""
Returns True if the user has any permissions in the given app label.
Uses pretty much the same logic as has_perm, above.
"""
# Active superusers have all permissions.
if self.is_active and self.is_superuser:
return True
return _user_has_module_perms(self, app_label)
any advice on this? thanks!
You don't have to let your class inherit from PermissionsMixin.
I had the same problem and I fixed it by adding a few required methods to my user class (in your case ShopUser).
class ShopUser(AbstractBaseUser):
...
def get_full_name(self):
return self.fullname
def get_short_name(self):
return self.shortname
#property
def is_superuser(self):
return self.is_admin
#property
def is_staff(self):
return self.is_admin
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return self.is_admin
Let the class ShopUser inherit from PermissionsMixin like so:
class ShopUser(AbstractBaseUser, PermissionsMixin):
This will add the is_superuser field and should play nicely with the admin UI.
Your create_superuser method should set user.is_superuser = True.
And finally, you should implement get_full_name and get_short_name for your ShopUser class.
More info here: Customizing authentication in Django