I have a Django application and the custom user - want to test it (do unit testing). My custom user is emailuser, which consists of e-mail and password fields. I want to set up something of such national mplayer, give it a field and a password. But my code below does not work.
settings.py
AUTH_USER_MODEL = 'custom_user.EmailUser'
My code in test.py
from django.test import TestCase
from django.conf import settings
class MyTest(TestCase):
def setUp(self):
self.user = settings.AUTH_USER_MODEL.objects.create('testuser#test.pl', 'testpass')
def test_user(self):
self.assertEqual(self.user, 'testuser#test.pl')
Well, try this:
from django.test import TestCase
from django.contrib.auth import get_user_model
User = get_user_model()
class CustomUserTestCase(TestCase):
def test_create_user(self):
# params = depends on your basemanager’s create_user methods.
user = User.objects.create(**params)
self.assertEqual(user.pk, user.id)
You should use the create_user() method instead of just create(). Also you should check the email field, not the user itself.
class MyTest(TestCase):
def setUp(self):
self.user = settings.AUTH_USER_MODEL.objects.create_user(
'testuser#test.pl', 'testpass')
def test_user(self):
self.assertEqual(self.user.email, 'testuser#test.pl')
Related
I have a custom user:
from django.contrib.auth.models import AbstractUser
# Create your models here.
class TaborUser(AbstractUser):
email = models.EmailField('E-mail', unique=True)
Its backend:
from django.contrib.auth.backends import BaseBackend
from django.contrib.auth import get_user_model
from django.db.models import Q
UserModel = get_user_model()
class EmailBackend(BaseBackend):
def get_user(self, user_id):
user = UserModel.objects.filter(pk=user_id)
breakpoint()
if user:
return user[0]
else:
return None
def authenticate(self, request, username=None, password=None, **kwargs):
user = UserModel.objects.filter(email=username)
if not user:
user = UserModel.objects.filter(username=username)
# Both username and e-mail are unique. As long as we don't have
# a very rogue admin, we should be alright.
if user:
user = user[0]
else:
return None
if user.check_password(password):
return user
else:
return None
The model does not seem to pass this check:
class AdminView(PermissionRequiredMixin, FormView):
form_class = UploadFileForm
template_name = "admin.html"
login_url = "/login/"
permission_required = ("taborapp.view_photomodel",
"taborapp.add_photomodel",
"taborapp.delete_photomodel",
)
When user is added as follows:
from taborapp.models import TaborUser
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
user = TaborUser.objects.create_user("test")
user.email = "test#example.me"
user.set_password("LOLaPublicPassword123")
permissions = []
photo_type = ContentType.objects.get(app_label="taborapp", model="photomodel")
for codename in "view_photomodel", "add_photomodel", "delete_photomodel":
perm = Permission.objects.filter(content_type=photo_type, codename=codename)
permissions.append(perm[0])
user.user_permissions.add(*permissions)
user.save()
Am I doing anything wrong? I went over docs and similar issues on stack overflow a few times and I just cannot figure out the issue.
I am too brief for the auto-detection system to believe me that I have described my problem enough. I hope this sentence will satisfy it.
Drop into the Django shell:
python manage.py shell
Next,
from django.contrib.auth.models import User
u = User.objects.get(email="test#example.me")
u.get_user_permissions()
Hopefully you'll see what you're looking for in the data returned. That'll give you a good idea of where to look next.
As pointed out by #RiverRook, getting the list of permissions was very helpful as I managed to find the correct thread about this.
Django user get_all_permissions() is empty while user_permissions is set
I am using a custom user model with builtin and custom authentication backends. the default for username-password login and the custom one for uid based login The login is working fine but the 'user' (Other than superuser) is not available in the template.Nor is the last_login getting updated in database. Here is my code
backend.py
from support.models import CustomUser
class UsernameIdModelBackend(object):
def authenticate(self, request, uid=None):
try:
user= CustomUser.objects.get(uid=uid)
return user
except CustomUser.DoesNotExist:
return None
def get_user(self, user_id):
try:
return CustomUser.objects.get(pk=user_id)
except CustomUser.DoesNotExist:
return None
models.py
from django.db import models
# Create your models here.
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
uid = models.CharField(max_length=50)
Where did i go wrong..
EDIT :
I was using if user.is_authenticated before the 'user'. After removing the if condition i am seeing AnonymousUser.
I have written a view to register a new user for my app but when I try running it, I get the error:
type object 'User' has no attribute 'objects'
My code looks as follows:
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.core import serializers
from rest_framework.views import APIView
from rest_framework.response import Response
from users.serializers import *
class Register(APIView):
def post(self, request):
serialized = UserSerializer(data=request.DATA)
if serialized.is_valid():
user = User.objects.create_user(serialized.init_data['email'], serialized.init_data['username'], serialized.init_data['password'])
return Response(serialized.data, status=status.HTTP_201_CREATED)
else:
return Response(serialized._errors, status=status.HTTP_400_BAD_REQUEST)
Edit:
My user.serializers module looks as follows:
from django.forms import widgets
from rest_framework import serializers
from django.contrib.auth import get_user_model
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = get_user_model()
fields = ('date_joined','email','first_name','id','last_login','last_name','username')
If you are in any case making a CustomUser and a CustomAccountManager
class CustomAccountManager(BaseUserManager):
......
.....
...
class CustomUser(AbstractBaseUser, PermissionsMixin):
......
# make sure it is [objects] and not [object]
objects = CustomAccountManager()
....
...
Do you have a class named User in your serializers module? You're doing from users.serializers import * which will import everything in that module into the current namespace, overriding any names you've already imported. That syntax is usually a bad idea for exactly that reason
Okay, I've fixed it, but I think the error has arisen from some issue with my environment setup. I have nevertheless found a way around it. I replaced the following line:
user = User.objects.create_user(serialized.init_data['email'], serialized.init_data['username'], serialized.init_data['password'])
with:
user = get_user_model().objects.create_user(serialized.init_data['username'], email=serialized.init_data['email'], password=serialized.init_data['password'])
I obviously also had to import:
from django.contrib.auth import get_user_model
I haven't figured out why I needed to use get_user_model() instead of just being able to use my User object directly, but this solved my problem.
I am new to django testing and have some issues using them to test relationship between models.
Here is an extract of my models:
class Member(models.Model):
user = models.OneToOneField('auth.User')
points = models.IntegerField()
def __unicode__(self):
return self.points
def get_number_of_poll(self):
nbr_of_poll = Poll.objects.filter(user=self.user).count()
return nbr_of_poll
class Poll(models.Model):
question = models.CharField(max_length=200)
user = models.ForeignKey(User)
def __unicode__(self):
return self.question
And here are the tests:
from polls.models import Member, Poll
from django.contrib.auth.models import User
from django.test import TestCase
class MemberTestCase(TestCase):
def setUp(self):
user = User(username='user')
self.member = Member(user=user, points=5000)
poll = Poll(question='poll', user=user)
def test_get_number_of_poll(self):
self.assertEqual(self.member.get_number_of_poll(), 1)
The issue is with the test_get_number_of_poll() method that always returns 0. The code works as expected on the site.
Am I doing something wrong with the test? I am not sure how I am supposed to set the poll in the test class.
You don't save any of the items you create in your setUp method. Instantiating a model object doesn't save it to the database: you should either call save() on them, or just use User.objects.create(username='user') etc which does the save for you.
The problem is that
poll = Poll(question='poll', user=user)
Only instantiates the Poll object, use the manager to actually save the object, e.g.
poll = Poll.objects.create(question='poll', user=user)
I'm trying to use a User model inheritance in my django application. Model looks like this:
from django.contrib.auth.models import User, UserManager
class MyUser(User):
ICQ = models.CharField(max_length=9)
objects = UserManager()
and authentication backend looks like this:
import sys
from django.db import models
from django.db.models import get_model
from django.conf import settings
from django.contrib.auth.models import User, UserManager
from django.contrib.auth.backends import ModelBackend
from django.core.exceptions import ImproperlyConfigured
class AuthBackend(ModelBackend):
def authenticate(self, email=None, username=None, password=None):
try:
if email:
user = self.user_class.objects.get(email = email)
else:
user = self.user_class.objects.get(username = username)
if user.check_password(password):
return user
except self.user_class.DoesNotExist:
return None
def get_user(self, user_id):
try:
return self.user_class.objects.get(pk=user_id)
except self.user_class.DoesNotExist:
return None
#property
def user_class(self):
if not hasattr(self, '_user_class'):
self._user_class = get_model(*settings.CUSTOM_USER_MODEL.split('.', 2))
if not self._user_class:
raise ImproperlyConfigured('Could not get custom user model')
return self._user_class
But if I'm trying to authenticate - there is an "MyUser matching query does not exist" error on the self.user_class.objects.get(username = username) call. It looks like admin user created on base syncing (I'm using sqlite3) stores into User model instead of MyUser (username and password are right). Or it's something different?
What I'm doing wrong? This is an example from http://scottbarnham.com/blog/2008/08/21/extending-the-django-user-model-with-inheritance/
Contrary to what the blog post you linked to says, storing this kind of data in a profile model is still the recommended way in Django. Subclassing User has all kinds of problems, one of which is the one you are hitting: Django has no idea you have subclassed User and happily creates and reads User models within the Django code base. The same is true for any other 3rd party app you might like to use.
Have a look at this ticket on Django's issue tracker to get some understanding of the underlying problems of subclassing User