I am getting the error below. I think that for some reason my UserMixin import does not include the has_role property that #role_required requires. Do I need to use RoleMixin. Can anyone help?
Traceback (most recent call last):
File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask_debugtoolbar/__init__.py", line 125, in dispatch_request
return view_func(**req.view_args)
File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask_login.py", line 792, in decorated_view
return func(*args, **kwargs)
File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/flask_user/decorators.py", line 69, in decorated_view
if not current_user.has_roles(*role_names):
File "/Users/henry.arnold/anaconda/lib/python3.5/site-packages/werkzeug/local.py", line 338, in __getattr__
return getattr(self._get_current_object(), name)
AttributeError: 'User' object has no attribute 'has_roles'
My model
import datetime as dt
from flask_login import UserMixin
from flaskapp.database import Column, Model, SurrogatePK, db
from flaskapp.teams.models import Teams
class User(UserMixin, SurrogatePK, Model):
"""A user of the app."""
__tablename__ = 'users'
user_id = Column(db.BigInteger, unique=True, nullable=False)
first_name = Column(db.String(30), nullable=True)
last_name = Column(db.String(80), nullable=True)
email = Column(db.String(80), unique=True, nullable=False)
isaf_id = Column(db.String(10), nullable=True)
primary_team_id = Column(db.Integer, db.ForeignKey(Teams.id), nullable=True)
primary_team = db.relationship('Teams', foreign_keys='User.primary_team_id')
is_admin = Column(db.Boolean(), default=False)
created_at = Column(db.DateTime, nullable=False, default=dt.datetime.utcnow)
roles = db.relationship('Role', secondary='user_roles',
backref=db.backref('users', lazy='dynamic'))
def __init__(self, user_id=user_id, first_name=first_name, last_name=last_name, email=email, is_admin=is_admin, **kwargs):
"""if int(user_id) in current_app.config['ADMINS']:
self.is_admin = True
else:
self.is_admin = False"""
db.Model.__init__(self, user_id=user_id, first_name=first_name, last_name=last_name, email=email, is_admin=is_admin, **kwargs)
"""Create instance."""
#property
def full_name(self):
"""Full user name."""
return '{0} {1}'.format(self.first_name, self.last_name)
def __repr__(self):
"""Represent instance as a unique string."""
return '{0} {1}'.format(self.first_name, self.last_name)
# Define Role model
class Role(db.Model):
role_id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(50), unique=True)
# Define UserRoles model
class UserRoles(db.Model):
id = db.Column(db.Integer(), primary_key=True)
user_id = db.Column(db.Integer(), db.ForeignKey('users.user_id', ondelete='CASCADE'))
role_id = db.Column(db.Integer(), db.ForeignKey('role.role_id', ondelete='CASCADE'))
to create the user I do the following
#blueprint.route('/callback/<provider>')
def oauth_callback(provider):
if not current_user.is_anonymous:
return redirect(url_for('public.home'))
oauth = OAuthSignIn.get_provider(provider)
user_id, first_name, last_name, email, is_admin = oauth.callback()
if user_id is None:
flash('Authentication failed.')
return redirect(url_for('public.home'))
user = User.query.filter_by(user_id=user_id).first()
if not user:
User.create(user_id=user_id, first_name=first_name, last_name=last_name, email=email, is_admin = is_admin)
user = User.query.filter_by(user_id=user_id).first()
if is_admin:
print('is admin')
admin = Role.query.filter(Role.name == 'admin').first()
user.roles.append(admin)
User.query.filter_by(user_id=user_id).update({'is_admin': True})
else:
print('is not admin')
User.query.filter_by(user_id=user_id).update({'is_admin': False})
login_user(user, True)
db.session.commit()
return redirect(url_for('public.home'))
I think check the user is an admin
from flask import Blueprint, flash, redirect, render_template, request, url_for
from flask_login import current_user, login_required
from flask_user import roles_required
from flaskapp.events.forms import CreateEventForm
from flaskapp.events.models import Events
from flaskapp.database import db
from datetime import date
from collections import OrderedDict
#blueprint.route('/add_event', methods=['POST', 'GET'])
#login_required
#roles_required('admin')
def add_event():
UserMixin class from flask_login does not provide has_roles attribute (source). You can provide it by yourself in your User class:
class User(UserMixin, SurrogatePK, Model):
# ... Everything that you've written so far
def has_roles(self, *args):
return set(args).issubset({role.name for role in self.roles})
Also, you can use UserMixin class not from flask_login module, but from flask_user module (yes, there is a confusion in names). The latter class indeed does provide has_roles method. In this case all you need to do is change this line
from flask_login import UserMixin
to this:
from flask_user import UserMixin
Related
I have written a model for my django project.
This is my model
from django.utils.translation import ugettext_lazy as _
from django.db import models
from django.utils.crypto import get_random_string
from django.db import models
from django.contrib.auth.models import(
BaseUserManager,
AbstractBaseUser,
PermissionsMixin,
)
def generate_vid():
"""Generates a vid for the users"""
not_unique = True
while not_unique:
vid = get_random_string(10, 'abcdefg0123456789')
if not User.objects.filter(v_id = vid).exists():
not_unique=False
return vid
class UserManager(BaseUserManager):
"""Model for user manager"""
def create_user(self, username, password, **params):
"""Create and return a user"""
u_type = params.pop('usertype','v')
params.update({'usertype':u_type})
p_username = params.pop('parent_username', 0)
if(u_type=='v'):
pass
else:
parent_id = User.objects.filter(username = p_username).values_list('v_id')
params.update({'parent_id': parent_id})
user = self.model(username=username, **params)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, username, password, **params):
"""Create and return a user"""
params.setdefault('is_staff',True)
params.setdefault('is_superuser',True)
params.setdefault('is_active',True)
if params.get('is_staff') is not True:
raise ValueError(_('Superuser must have is_staff=True.'))
if params.get('is_superuser') is not True:
raise ValueError(_('Superuser must have is_superuser=True.'))
return self.create_user(username, password, **params)
class User(AbstractBaseUser, PermissionsMixin):
"""Models for user"""
v_id = models.CharField(
max_length=10,
default=generate_vid,
primary_key = True,
)
username = models.CharField(max_length=20, unique=True)
email = models.EmailField(blank=True, unique = True)
parent_id = models.ForeignKey('User', on_delete=models.SET_DEFAULT, default=0)
usertype = models.CharField(max_length=1, choices=[('f', 'family'), ('v', 'veteran')])
REQUIRED_FIELDS = ['usertype']
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
USERNAME_FIELD = 'username'
objects = UserManager()
def __str__(self):
return self.username
Now I want to impose the condition while creating a user such that every time I provide usertype=f, and I provide a username(say username='Test")
the parent_id of that particular entry is automatically set as the v_id of the username provided.
The parent_id is a self referential foreignkey.
This is the error showing while testing the feature
File "/py/lib/python3.9/site-packages/rest_framework/serializers.py", line 205, in save
self.instance = self.create(validated_data)
File "/app/user/serializers.py", line 17, in create
return get_user_model().objects.create_user(**validated_data)
File "/app/base/models.py", line 39, in create_user
user = self.model(username=username, **params)
File "/py/lib/python3.9/site-packages/django/db/models/base.py", line 485, in __init__
_setattr(self, field.name, rel_obj)
File "/py/lib/python3.9/site-packages/django/db/models/fields/related_descriptors.py", line 215, in __set__
raise ValueError(
ValueError: Cannot assign "<QuerySet []>": "User.parent_id" must be a "User" instance.
I think you can try signals to set data after creating a user account. You can choose from several types, but I would recommend you focus on pre_save and post_save.
UPDATE
I wrote examples, but the website will probably better illustrate it. In general, there are quite a few signals, but the most commonly used are pre_save and post_save.
#2 UPDATE
Try use a first or latest. Details in documentation.
parent_id = User.objects.filter(username = p_username).first()
I am still in learning phase and having this issue while going through tutorials
I do not understand why I am getting this error ValueError: Invalid salt
Complete Error Code is:
File "C:\Users\Aparichit\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py",
line 1515, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\Aparichit\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py",
line 1513, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\Aparichit\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py",
line 1499, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "C:\Users\Aparichit\Desktop\NoViewsIndia\noViews\views.py", line 46, in login_page
if attempted_user and bcrypt.check_password_hash(attempted_user.password_hash,
attempted_password):
File "C:\Users\Aparichit\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask_bcrypt.py",
line 193, in check_password_hash
return safe_str_cmp(bcrypt.hashpw(password, pw_hash), pw_hash)
File "C:\Users\Aparichit\AppData\Local\Programs\Python\Python39\Lib\site-packages\bcrypt_init_.py",
line 105, in hashpw
raise ValueError("Invalid salt")
My model.py code is:
class User(db.Model, UserMixin):
name = db.Column(db.String(20), nullable=False)
userName = db.Column(db.String(15), primary_key=True, nullable=False)
password_hash = db.Column(db.String(20), nullable=False)
#property
def password(self):
return self.password
#password.setter
def password(self, plain_text_password):
self.password_hash = bcrypt.generate_password_hash(plain_text_password).decode('utf-8')
And views.py is
#app.route('/admin_login', methods=['GET', 'POST'])
def login_page():
login_form =Login()
if login_form.validate_on_submit():
attempted_password = login_form.pWord.data
attempted_user = User.query.filter_by(userName = login_form.uName.data).first()
print(f'Route Username is {login_form.uName.data}')
print(f'Route User is {attempted_user}')
print(f' Route Password is {attempted_password}')
print(f'Route Hashed Password is {attempted_user.password_hash}')
if attempted_user and bcrypt.check_password_hash(attempted_user.password_hash, attempted_password):
login_user(attempted_user)
flash(f'You have successfully logged in, {attempted_user.name}')
else:
flash('Invalid Username and Password')
return render_template('admin_login.html', loginForm=login_form)
And form.py is
class Login(FlaskForm):
uName = StringField(label='User Name')
pWord = PasswordField(label='Password')
submit = SubmitField(label='Login')
And password that are saved:
Hassed Password
You need to decode your data before storing the data
pw_hash = bcrypt.generate_password_hash(‘hunter2’).decode(‘utf-8’)
read the docs
I have created a UserProfile model with OneToOne relationship with User model.
The UserProfile model is shown below.
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
mobile_number = models.IntegerField(blank=True, unique=True, null=True)
profile_image = models.ImageField(upload_to="media", blank=True )
current_location= models.CharField(max_length=300, unique=False, blank=True)
created_at = models.DateTimeField("created at", auto_now_add=True)
university = models.CharField(max_length=100, blank=True)
def __str__(self):
return self.user.username
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
The serializer class is shown below.
from rest_framework import serializers
from .models import UserProfile
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ( 'mobile_number',
'current_location'
,'university','profile_image')
Iam using token authentication. How can I use the ListCreateViewand other classes to implement the post, put ,get and delete method in the best way possible. I also need to validate these data before saving(like mobile_number length should be 10 and mandatory)
I tried to build a view as shown below.
from .models import UserProfile
from .serializers import UserProfileSerializer
class UserProfileView(ListCreateAPIView):
queryset = UserProfile.objects.all()
print(queryset)
serializer_class = UserProfileSerializer
def get_queryset(self):
return UserProfile.objects.filter(user=self.request.user)
def perform_create(self, serializer):
profile = get_object_or_404(UserProfile, user=self.request.user)
print(str(self.request.user.id)+"..."+str(profile))
return serializer.save(userprofile=profile)
But it gives me error:
Got a `TypeError` when calling `UserProfile.objects.create()`. This may be because you have a writable field on the serializer class that is not a valid argument to `UserProfile.objects.create()`. You may need to make the field read-only, or override the UserProfileSerializer.create() method to handle this correctly.
how can I solve the problem.
The stack trace is shown below
Internal Server Error: /users/userprofile
Traceback (most recent call last):
File "/home/vishnu/.local/lib/python3.6/site-packages/rest_framework/serializers.py", line 932, in create
instance = ModelClass._default_manager.create(**validated_data)
File "/home/vishnu/.local/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/vishnu/.local/lib/python3.6/site-packages/django/db/models/query.py", line 420, in create
obj = self.model(**kwargs)
File "/home/vishnu/.local/lib/python3.6/site-packages/django/db/models/base.py", line 501, in __init__
raise TypeError("%s() got an unexpected keyword argument '%s'" % (cls.__name__, kwarg))
TypeError: UserProfile() got an unexpected keyword argument 'userprofile'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/vishnu/.local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/vishnu/.local/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/vishnu/.local/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/vishnu/.local/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/vishnu/.local/lib/python3.6/site-packages/django/views/generic/base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "/home/vishnu/.local/lib/python3.6/site-packages/rest_framework/views.py", line 505, in dispatch
response = self.handle_exception(exc)
File "/home/vishnu/.local/lib/python3.6/site-packages/rest_framework/views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "/home/vishnu/.local/lib/python3.6/site-packages/rest_framework/views.py", line 476, in raise_uncaught_exception
raise exc
File "/home/vishnu/.local/lib/python3.6/site-packages/rest_framework/views.py", line 502, in dispatch
response = handler(request, *args, **kwargs)
File "/home/vishnu/.local/lib/python3.6/site-packages/rest_framework/generics.py", line 242, in post
return self.create(request, *args, **kwargs)
File "/home/vishnu/.local/lib/python3.6/site-packages/rest_framework/mixins.py", line 19, in create
self.perform_create(serializer)
File "/home/vishnu/git_repos/Agora42core/users/views.py", line 23, in perform_create
return serializer.save(userprofile=profile)
File "/home/vishnu/.local/lib/python3.6/site-packages/rest_framework/serializers.py", line 213, in save
self.instance = self.create(validated_data)
File "/home/vishnu/.local/lib/python3.6/site-packages/rest_framework/serializers.py", line 951, in create
raise TypeError(msg)
TypeError: Got a `TypeError` when calling `UserProfile.objects.create()`. This may be because you have a writable field on the serializer class that is not a valid argument to `UserProfile.objects.create()`. You may need to make the field read-only, or override the UserProfileSerializer.create() method to handle this correctly.
Original exception was:
Traceback (most recent call last):
File "/home/vishnu/.local/lib/python3.6/site-packages/rest_framework/serializers.py", line 932, in create
instance = ModelClass._default_manager.create(**validated_data)
File "/home/vishnu/.local/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/vishnu/.local/lib/python3.6/site-packages/django/db/models/query.py", line 420, in create
obj = self.model(**kwargs)
File "/home/vishnu/.local/lib/python3.6/site-packages/django/db/models/base.py", line 501, in __init__
raise TypeError("%s() got an unexpected keyword argument '%s'" % (cls.__name__, kwarg))
TypeError: UserProfile() got an unexpected keyword argument 'userprofile'
If you're really creating a new UserProfile object, your perform_create() method should just pass the user into the serialiser's save() method:
def perform_create(self, serializer):
return serializer.save(user=self.request.user)
But if you already have a UserProfile, which looks like it's what your expecting since you're using get_object_or_404, then you should use a UpdateAPIView instead of a ListCreateAPIView:
class UserProfileView(UpdateAPIView):
serializer_class = UserProfileSerializer
permission_classes = [IsAuthenticated]
def get_queryset(self):
return UserProfile.objects.filter(user=self.request.user)
For PUT, PATCH, you need to define(override) create and update
Validation can be done at two levels. Both are shown below:
At Serializer level,
it is just validate_field_variable_name
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ( 'mobile_number',
'current_location'
,'university','profile_image')
#For POST
def create(self, validated_data):
<your code,>
#for PATCH
def update(self, instance, validated_data):
<your code,>
#Validation
def validate_mobile_number(self, cell_number):
#Validate code here
More:
https://www.django-rest-framework.org/api-guide/validators/
Validation at Model level:
You can also do this kind of validation at model level, like length of string etc.
Particular to mobile number, there are other modules which can do this unless you want special cases to handle.
from django.db import models
from phone_field import PhoneField
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
mobile_number = PhoneField(blank=True, unique=True, null=True)
https://pypi.org/project/django-phone-field/
My custom User model have a TimeZoneField:
from timezone_field import TimeZoneField
class User(AbstractBaseUser, PermissionsMixin):
class Meta:
verbose_name = _('user')
verbose_name_plural = _('users')
email = models.EmailField(_('email address'), unique=True, blank=False, null=False)
username = models.CharField(_('user name'), max_length=128, unique=True, blank=False, null=False)
is_staff = models.BooleanField(
_('staff status'),
default=False,
help_text=_('Designates whether the user can log into this admin site.'))
is_active = models.BooleanField(
_('active'),
default=True,
help_text=_(
'Designates whether this user should be treated as active. '
'Unselect this instead of deleting accounts.'))
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
language = models.CharField(_('Language'), choices=settings.LANGUAGES, default=settings.ENGLISH, max_length=2)
timezone = TimeZoneField(verbose_name=_('Timezone'), default='Europe/London')
objects = UserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email']
I use django-allauth for registration by Google accounts. When existing user (registered by google email before, not Google Account) trying login by Google Account we have error:
<DstTzInfo 'Europe/London' LMT-1 day, 23:59:00 STD> is not JSON serializable
Traceback:
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/allauth/socialaccount/providers/oauth2/views.py" in view
55. return self.dispatch(request, *args, **kwargs)
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/allauth/socialaccount/providers/oauth2/views.py" in dispatch
125. return complete_social_login(request, login)
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/allauth/socialaccount/helpers.py" in complete_social_login
142. return _complete_social_login(request, sociallogin)
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/allauth/socialaccount/helpers.py" in _complete_social_login
158. ret = _process_signup(request, sociallogin)
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/allauth/socialaccount/helpers.py" in _process_signup
25. request.session['socialaccount_sociallogin'] = sociallogin.serialize()
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/allauth/socialaccount/models.py" in serialize
189. user=serialize_instance(self.user),
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/allauth/utils.py" in serialize_instance
194. return json.loads(json.dumps(data, cls=DjangoJSONEncoder))
File "/usr/lib/python3.4/json/__init__.py" in dumps
237. **kw).encode(obj)
File "/usr/lib/python3.4/json/encoder.py" in encode
192. chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python3.4/json/encoder.py" in iterencode
250. return _iterencode(o, 0)
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/django/core/serializers/json.py" in default
115. return super(DjangoJSONEncoder, self).default(o)
File "/usr/lib/python3.4/json/encoder.py" in default
173. raise TypeError(repr(o) + " is not JSON serializable")
Exception Type: TypeError at /accounts/google/login/callback/
Exception Value: <DstTzInfo 'Europe/London' LMT-1 day, 23:59:00 STD> is not JSON serializable
What are some ways to serialize a custom field in allauth?
My solution is replace default DefaultSocialAccountAdapter and extension serialize_instance (from allauth.utils) for serializing TimeZoneField. Don't forget set custom adapret in project settings:
SOCIALACCOUNT_ADAPTER = 'myapp.adapter.MySocialAccountAdapter'
Also I replaced pre_social_login for association Social account with Direct account (registered by email) (Thanks elssar for his example: https://stackoverflow.com/a/19443127/4012716)
myapp.adapter.py:
import json
import base64
import logging
from django.db.models import FieldDoesNotExist, FileField
from django.db.models.fields import (BinaryField)
from django.utils import six
from django.core.serializers.json import DjangoJSONEncoder
from django.shortcuts import HttpResponse
try:
from django.utils.encoding import force_text
except ImportError:
from django.utils.encoding import force_unicode as force_text
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from allauth.account.adapter import DefaultAccountAdapter
from allauth.utils import SERIALIZED_DB_FIELD_PREFIX
from allauth.exceptions import ImmediateHttpResponse
from timezone_field import TimeZoneField
from accounts.models import User
logger = logging.getLogger("django")
def my_serialize_instance(instance):
"""Instance serializer supported of serialization of TimeZoneField.
:param instance:
:return:
"""
data = {}
for k, v in instance.__dict__.items():
if k.startswith('_') or callable(v):
continue
try:
field = instance._meta.get_field(k)
if isinstance(field, BinaryField):
v = force_text(base64.b64encode(v))
elif isinstance(field, FileField):
if not isinstance(v, six.string_types):
v = v.name
elif isinstance(field, TimeZoneField):
v = six.text_type(v.zone)
# Check if the field is serializable. If not, we'll fall back
# to serializing the DB values which should cover most use cases.
try:
json.dumps(v, cls=DjangoJSONEncoder)
except TypeError:
v = field.get_prep_value(v)
k = SERIALIZED_DB_FIELD_PREFIX + k
except FieldDoesNotExist:
pass
data[k] = v
return json.loads(json.dumps(data, cls=DjangoJSONEncoder))
class MySocialAccountAdapter(DefaultSocialAccountAdapter):
"""Custom SocialAccountAdapter for django-allauth.
Replaced standard behavior for serialization of TimeZoneField.
Need set it in project settings:
SOCIALACCOUNT_ADAPTER = 'myapp.adapter.MySocialAccountAdapter'
"""
def __init__(self, request=None):
super(MySocialAccountAdapter, self).__init__(request=request)
def pre_social_login(self, request, sociallogin):
# This isn't tested, but should work
try:
emails = [email.email for email in sociallogin.email_addresses]
user = User.objects.get(email__in=emails)
sociallogin.connect(request, user)
raise ImmediateHttpResponse(response=HttpResponse())
except User.DoesNotExist:
pass
except Exception as ex:
logger.error(ex)
def serialize_instance(self, instance):
return my_serialize_instance(instance)
My question seems similar to this one, but the answer and explanation did not seem adequate, so I'm going ahead with a custom auth_user_model issue that is beyond my understanding. My app/users/model.py is like so:
from django.contrib.auth.models import (
BaseUserManager,AbstractBaseUser)
from django.contrib.auth.models import PermissionsMixin
from django.db import models
class MyUserManager(BaseUserManager):
def create_user(self, email, password,name=''):
"""
Creates and saves a User with the given email, password
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email),
name=name
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self,email,password,name=''):
user = self.create_user(email,name=name,password=password)
user.is_admin = True
user.is_active = True
user.is_superuser = True
user.save(using=self._db)
return user
class MyUser(AbstractBaseUser,PermissionsMixin):
email = models.EmailField(
verbose_name='email',
max_length=255,
unique=True,
)
name = models.CharField(max_length=255,blank=True,default='')
is_active = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
objects = MyUserManager()
USERNAME_FIELD = 'email'
#REQUIRED_FIELDS = ['name']
def get_full_name(self):
return self.name if self.name else self.email
def get_short_name(self):
return self.email
def __unicode__(self):
return self.email
#property
def is_staff(self):
return self.is_superuser
My stack trace is as follows:
Traceback (most recent call last):
File "manage.py", line 10, in <module> execute_from_command_line(sys.argv)
File "/.virtualenvs/project/lib/python2.7/site-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
utility.execute()
File "/.virtualenvs/project/lib/python2.7/site-packages/django/core/management/__init__.py", line 330, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/.virtualenvs/project/lib/python2.7/site-packages/django/core/management/base.py", line 393, in run_from_argv
self.execute(*args, **cmd_options)
File "/.virtualenvs/project/lib/python2.7/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 50, in execute
return super(Command, self).execute(*args, **options)
File "/.virtualenvs/project/lib/python2.7/site-packages/django/core/management/base.py", line 444, in execute
output = self.handle(*args, **options)
File "/.virtualenvs/project/lib/python2.7/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 149, in handle
self.UserModel._default_manager.db_manager(database).create_superuser(**user_data)
AttributeError: 'MyUserManager' object has no attribute 'create_superuser'
I cant for the life of me figure out why this error is occuring. I'm using Django 1.9.1, with Python 2.7.11, with pydanny's cookiecutter django module. Relevant installed apps include djstripe, and allauth. Djstripe mostly works under these conditions, but I am unable to create a superuser, or login to the admin area.
At a loss here, so I hope a Django jedi can steer me in better direction, with some type of explanation. Thanks