'StateApps' object has no attribute 'label' while running migration - django

As I am trying to run the this migration:
def add_user_data(apps, schema_editor):
Group = apps.get_model('auth', 'Group')
Permission = apps.get_model(
'auth', 'Permission')
Profile = apps.get_model('user', 'Profile')
User = apps.get_model('user', 'User')
andrew_user = User.objects.create(
email='django#jambonsw.com',
password=make_password('hunter2'),
is_active=True,
is_staff=True,
is_superuser=True)
andrew_profile = Profile.objects.create(
user=andrew_user,
name='Andrew',
slug='andrew',
about='The author of this site!')
ada_user = User.objects.create(
email='ada#djangogirls.org',
password=make_password('algorhythm'),
is_active=True,
is_staff=True,
is_superuser=False)
ada_profile = Profile.objects.create(
user=ada_user,
name='Ada Lovelace',
slug='the_countess',
about=(
' '))
contributors = Group.objects.create(
name='contributors')
ada_user.groups.add(contributors)
permissions = [
'add_post',
'change_post',
]
for perm in permissions:
contributors.permissions.add(
Permission.objects.get(
codename=perm,
content_type__app_label='blog'))
def remove_user_data(apps, schema_editor):
Group = apps.get_model('auth', 'Group')
Profile = apps.get_model('user', 'Profile')
User = apps.get_model('user', 'User')
Profile.objects.get(slug='andrew').delete()
Profile.objects.get(
slug='the_countess').delete()
User.objects.get(
email='django#jambonsw.com').delete()
User.objects.get(
email='ada#djangogirls.org').delete()
Group.objects.get(
name='contributors').delete()
class Migration(migrations.Migration):
dependencies = [
('blog', '0005_post_permissions'),
('user', '0002_profile'),
]
operations = [
migrations.RunPython(
add_user_data,
remove_user_data)
]
I ran in this error:
AttributeError: 'StateApps' object has no attribute 'label'
I don't really know what the 'StateApps' does. But As the error message states it has something to do with assigning the permissions. Can someone help? This code is from a tutorial using Django 1.8 so I think that it is django 1.11 which is making the code error.

Change generate_permissions function in blog/migrations/0005_post_permissions.py:
def generate_permissions(apps, schema_editor):
Permission = apps.get_model('auth', 'Permission')
try:
Permission.objects.get(
codename='add_post',
content_type__app_label='blog')
except Permission.DoesNotExist:
app_config = apps.get_app_config('blog')
if app_config.models_module is None:
app_config.models_module = True
create_permissions(app_config, verbosity=0)
app_config.models_module = None
else:
raise
It's work for me with django 2.1

Related

Flask-admin not recognising current_user in model View

I created my ModelView in flask-admin and want to give role choices to user such that only admin can create user with role manager,admin or user. And user shouldn't have choice to give admin privilidges or as such. I am trying this code but it's giving me:
AttributeError: 'NoneType' object has no attribute 'is_authenticated'
class UserView(ModelView):
column_exclude_list = ['logs', 'password_hash',]
form_excluded_columns = ['logs']
can_edit = True
if login.current_user or current_user.is_authenticated:
if login.current_user.role == 'a':
form_choices = {
'role': [ ('a', 'Admin'), ('m', 'Manager'), ('u', 'User') ]
}
if login.current_user.role == 'm':
form_choices = {
'role': [
('m', 'Manager'),
('u', 'User')
]
}
Any help would be highly appreciated.
Evaluating current_user always returns a NoneType unless it is within a Flask application context. Do something like the following:
def get_user_roles():
_roles = []
if current_user and current_user.is_authenticated:
if current_user.role == 'a':
_roles = [('a', 'Admin'), ('m', 'Manager'), ('u', 'User')]
elif login.current_user.role == 'm':
_roles = [('m', 'Manager'), ('u', 'User')]
return _roles
class UserView(ModelView):
form_choices = {
'role' : get_user_roles
}
Single file example. If you run this without logging in you will see only the "User" role in the role choices:
requirements.txt
Babel==2.11.0
blinker==1.5
click==8.1.3
colorama==0.4.6
dnspython==2.2.1
email-validator==1.3.0
Flask==2.2.2
Flask-Admin==1.6.0
Flask-BabelEx==0.9.4
Flask-Login==0.6.2
Flask-Mail==0.9.1
Flask-Principal==0.4.0
Flask-SQLAlchemy==3.0.2
Flask-WTF==1.0.1
greenlet==2.0.1
idna==3.4
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.1
passlib==1.7.4
pytz==2022.6
speaklater==1.3
SQLAlchemy==1.4.44
Werkzeug==2.2.2
WTForms==3.0.1
app.py
import os
from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash
import click
from flask import Flask, current_app
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
from flask_login import current_user, UserMixin, LoginManager
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
login_manager = LoginManager()
class User(db.Model, UserMixin):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.Unicode(length=255), nullable=False)
last_name = db.Column(db.Unicode(length=255), nullable=False, index=True)
# Identification Data: email & password
email = db.Column(db.Unicode(length=254), nullable=False, unique=True)
password = db.Column(db.Unicode(length=255), nullable=False)
active = db.Column(db.Boolean(), default=False)
role = db.Column(db.Unicode(length=255), nullable=False)
#login_manager.user_loader
def load_user(user_id):
return User.get(user_id)
basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
app.config['SECRET_KEY'] = '123456790'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'database.db')
db.init_app(app)
login_manager.init_app(app)
#app.cli.command('create-database', short_help='Create sample database')
def create_database():
"""
Create database
"""
db.drop_all()
db.create_all()
users = [
{
'email': 'paul#example.net',
'first_name': 'Paul',
'last_name': 'Cunningham',
'password': generate_password_hash('pa$$word'),
'active': True,
'role': 'a',
},
{
'email': 'jane#example.net',
'first_name': 'Jane',
'last_name': 'Smith',
'password': generate_password_hash('pa$$word'),
'active': True,
'role': 'm'
},
]
for user in users:
_user_db = User(**user)
db.session.add(_user_db)
db.session.commit()
#app.route('/')
def index(): # put application's code here
return 'Click me to get to Admin!'
admin = Admin(app, template_mode="bootstrap3")
def get_user_roles():
# default role is a user
_roles = [('u', 'User')]
if current_user and current_user.is_authenticated:
if current_user.has_role('a'):
print('Current user is an admin')
_roles = [('a', 'Admin'), ('m', 'Manager'), ('u', 'User')]
elif current_user.has_role('m'):
print('Current user is a manager')
_roles = [('m', 'Manager'), ('u', 'User')]
print(f"Roles assigned to role choices: {_roles}")
return _roles
class UserView(ModelView):
column_list = ('first_name', 'last_name', 'email', 'role')
form_columns = column_list
form_choices = {
'role': get_user_roles
}
admin.add_view(UserView(User, db.session))
if __name__ == '__main__':
app.run()
Run the following command to initialize an SQLite DB.
flask create-database

Flask Admin - how to set form_edit_rules or form_create_rules based on role of user?

I am making simple ticketing system for medium-sized organization using Flask and sqlite together with SQLAlchemy. For backend managing of data I use Flask-Admin.
The User and Ticket table looks like this:
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
role = db.Column(db.Integer, default=0)
vmc_kom = db.Column(db.String(20))
name = db.Column(db.String(30), nullable=False)
phone = db.Column(db.String, default="not")
email = db.Column(db.String(40), nullable=False)
password = db.Column(db.String(60), nullable=False)
tickets = db.relationship('Ticket', cascade="all,delete", backref='author', lazy=True)
def __repr__(self):
return f"('{self.name}')"
class Ticket(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key = True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
povod_vmc_kom = db.Column(db.String(20))
osoba = db.Column(db.String(20), default="XYZ")
dateVMC = db.Column(db.Date, nullable=False)
deadline = db.Column(db.Date, nullable=False)
is_finished = db.Column(db.Boolean, default = False)
images = db.relationship('Image_ticket', cascade="all,delete", backref='home_ticket', lazy=True)
solution = db.Column(db.Text)
date_solution = db.Column(db.DateTime)
zodpovedni = db.relationship("Zodpovedny", secondary="ticketutvary")
sprava = db.Column(db.String(100))
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
def __repr__(self):
return f"Ticket('{self.id}', '{self.title}', '{self.dateVMC}')"
I was able to set permission to create, edit or delete Tickets based on User.role set in is_accesible method.
class TicketModelView(ModelView):
column_list = ['id', 'title', 'osoba', 'content', 'povod_vmc_kom', 'dateVMC','zodpovedni', 'deadline', 'solution']
def is_accessible(self):
if current_user.is_authenticated and current_user.role == 0:
self.can_export=True
self.can_delete = False
self.can_edit = False
self.can_create = False
return True
if current_user.is_authenticated and current_user.role == 1:
self.can_export=True
self.can_delete=True
return True
if current_user.is_authenticated and current_user.role == 2:
self.can_delete = False
self.can_export=True
return True
if current_user.is_authenticated and current_user.role == 3:
self.can_delete = False
self.can_export=True
return True
return False
But I´ve been struggling really hard to set form_edit_rules for specific user. For example I want to allow User with role == 2 to edit only two columns in Ticket. When I put form_edit_rules directly in ModelView Class it works but for everybody. I also tried this:
class TicketModelView(ModelView):
column_list = ['id', 'title', 'osoba', 'content', 'povod_vmc_kom', 'dateVMC','zodpovedni', 'deadline', 'solution']
def is_accessible(self):
if current_user.is_authenticated and current_user.role == 2:
self.can_export=True
self.can_delete = False
self.can_edit = False
self.can_create = False
self.form_edit_rules = ('zodpovedni','dateVMC')
return True
But no success.
Please can anyone push me right direction? Is there something I am missing? Is there some really bad practise used?
Thanks in advance.
form_edit_rules is already cached by the time method is_accessible is called. If you update the rules then refresh the cache:
class TicketModelView(ModelView):
column_list = ['id', 'title', 'osoba', 'content', 'povod_vmc_kom', 'dateVMC','zodpovedni', 'deadline', 'solution']
def is_accessible(self):
if current_user.is_authenticated and current_user.role == 2:
self.can_export=True
self.can_delete = False
self.can_edit = False
self.can_create = False
self.form_edit_rules = ('zodpovedni','dateVMC')
# Refresh form rules cache
self._refresh_form_rules_cache()
return True
return False
It is also possible to set the form_edit_rules at runtime without resorting to invalidating the rules cache. I used this SO Q/A flask-admin: how to allow only super users can view the specified table column? as the basis for the following. If the user is logged in and is has role 'admin' they can see and use the 'active' field.
class AuthorView(sqla.ModelView):
column_default_sort = ('last_name', False)
column_searchable_list = ('first_name', 'last_name')
#property
def _form_edit_rules(self):
return rules.RuleSet(self, self.form_edit_rules)
#_form_edit_rules.setter
def _form_edit_rules(self, value):
pass
#property
def form_edit_rules(self):
if not has_app_context() or current_user.has_role('admin'):
return ('first_name', 'last_name', rules.Text(f'Authenticated User has Admin role'), 'active')
return ('first_name', 'last_name', rules.Text('Not Authenticated and/or not Admin role'))
Full single file Python 3 example below.
requirements.txt
Babel==2.8.0
blinker==1.4
click==7.1.2
dnspython==2.0.0
email-validator==1.1.1
Faker==4.1.1
Flask==1.1.2
Flask-Admin==1.5.6
Flask-BabelEx==0.9.4
Flask-Login==0.5.0
Flask-Mail==0.9.1
Flask-Principal==0.4.0
Flask-Security==3.0.0
Flask-SQLAlchemy==2.4.4
Flask-WTF==0.14.3
idna==2.10
itsdangerous==1.1.0
Jinja2==2.11.2
MarkupSafe==1.1.1
passlib==1.7.2
python-dateutil==2.8.1
pytz==2020.1
six==1.15.0
speaklater==1.3
SQLAlchemy==1.3.18
text-unidecode==1.3
Werkzeug==1.0.1
WTForms==2.3.3
app.py
from datetime import datetime
from faker import Faker
import click
from flask import Flask, has_app_context, current_app
from flask_admin.form import rules
from flask_login import login_user, logout_user
from flask_security import UserMixin, RoleMixin, current_user, SQLAlchemyUserDatastore, Security
from flask_security.utils import hash_password
from flask_sqlalchemy import SQLAlchemy
from flask_admin import Admin
from flask_admin.contrib import sqla
db = SQLAlchemy()
user_to_role = db.Table('user_to_role',
db.Column('user_id', db.Integer(), db.ForeignKey('users.id')),
db.Column('role_id', db.Integer(), db.ForeignKey('roles.id')))
class User(db.Model, UserMixin):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.Unicode(length=255), nullable=False)
last_name = db.Column(db.Unicode(length=255), nullable=False, index=True)
# Identification Data: email & password
email = db.Column(db.Unicode(length=254), nullable=False, unique=True)
password = db.Column(db.Unicode(length=255), nullable=False)
active = db.Column(db.Boolean(), default=False)
roles = db.relationship('Role', secondary=user_to_role, backref=db.backref('users', lazy='select'))
class Role(db.Model, RoleMixin):
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Unicode(length=64), unique=True)
description = db.Column(db.Unicode(length=255), nullable=True)
def __str__(self):
return self.name
class Author(db.Model):
__tablename__ = 'authors'
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.Text(length=255), nullable=False)
last_name = db.Column(db.Text(length=255), nullable=False)
active = db.Column(db.Boolean(), default=False)
def __str__(self):
return f"ID: {self.id}; First Name: {self.first_name}; Last Name: {self.last_name}"
app = Flask(__name__)
app.config['SECRET_KEY'] = '123456790'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///sample.sqlite'
app.config['SECURITY_PASSWORD_HASH'] = 'pbkdf2_sha512'
app.config['SECURITY_PASSWORD_SALT'] = 'c1b4797ffb4783bb4aed7e14a1494a01390eacf94ee324b9'
db.init_app(app)
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)
#app.cli.command('create-database', short_help='Create sample database')
#click.option('--count', default=100, help='Number of authors (default 100)')
def create_database(count):
"""
Create database
"""
db.drop_all()
db.create_all()
_faker = Faker()
security = current_app.extensions.get('security')
_admin_role = security.datastore.find_or_create_role(name="admin", description='Administers the system')
_user_role = security.datastore.find_or_create_role(name="user", description='Uses the system')
users = [
{'email': 'paul#example.net', 'first_name': 'Paul', 'last_name': 'Cunningham', 'password': hash_password('pa$$word'), 'role': _user_role},
{'email': 'jane#example.net', 'first_name': 'Jane', 'last_name': 'Smith', 'password': hash_password('pa$$word'), 'role': _admin_role},
]
for user in users:
_role = user.pop('role')
_user_db = security.datastore.create_user(**user)
if _role:
security.datastore.add_role_to_user(_user_db, _role)
security.datastore.activate_user(_user_db)
_user_db.confirmed_at = datetime.utcnow()
security.datastore.commit()
for _ in range(0, count):
_author = Author(
first_name=_faker.first_name(),
last_name=_faker.last_name(),
active=_faker.boolean()
)
db.session.add(_author)
db.session.commit()
class AuthorView(sqla.ModelView):
column_default_sort = ('last_name', False)
column_searchable_list = ('first_name', 'last_name')
#property
def _form_edit_rules(self):
return rules.RuleSet(self, self.form_edit_rules)
#_form_edit_rules.setter
def _form_edit_rules(self, value):
pass
#property
def form_edit_rules(self):
if not has_app_context() or current_user.has_role('admin'):
return ('first_name', 'last_name', rules.Text(f'Authenticated User has Admin role'), 'active')
return ('first_name', 'last_name', rules.Text('Not Authenticated and/or not Admin role'))
# Flask views
#app.route('/')
def index():
_html = [
'Click me to get to impersonate Paul (user)!',
'Click me to get to impersonate Jane (admin)!'
]
return '<br>'.join(_html)
#app.route('/impersonate-paul')
def impersonate_paul():
_impersonate_user = User.query.filter(User.email == 'paul#example.net').first()
logout_user()
login_user(_impersonate_user)
return 'Click me to get to Admin logged in as Paul (user)!'
#app.route('/impersonate-jane')
def impersonate_jane():
_impersonate_user = User.query.filter(User.email == 'jane#example.net').first()
logout_user()
login_user(_impersonate_user)
return 'Click me to get to Admin logged in as Jane (admin)!'
admin = Admin(app, template_mode="bootstrap3")
admin.add_view(AuthorView(Author, db.session))
if __name__ == '__main__':
app.run()
Run the following command to initialize an SQLite DB.
flask create-database --count 100

Django Rest Framework:RecursionError at /profile/ maximum recursion depth exceeded while calling a Python object

I have completed my project on social networking and setting an option for logout
MeanWhile I came across django-rest-auth app and tried to use it but later choose to do it by myself so, deleted it from settings.py and urls.py and used "pip uninstall django-rest-auth" to clear out things.
Now when i try to create a new user It gives me this error:
RecursionError at /profile/
maximum recursion depth exceeded while calling a Python object
models.py
class Profile(models.Model):
user = models.OneToOneField(User,related_name='profile',on_delete=models.CASCADE)
location = models.CharField(max_length=30,blank=True)
friends_count = models.PositiveIntegerField(default=0)
profile_pic = models.FileField(upload_to='profile_pics/',blank=False,null=True)
def natural_key(self):
return (self.user.username,)
views.py:
class UserCreateAPIViewSet(viewsets.ModelViewSet):
""""A View which handles Creating and Updating User Profile"""
serializer_class = UserProfileCreateSerializer
queryset = User.objects.all()
authentication_classes = (TokenAuthentication,)
permission_classes = (permissions.UpdateOwnProfile,)
filter_backends = (filters.SearchFilter,)
search_fields = ('username','email',)
urls.py:
router.register(r'profile',views.UserCreateAPIViewSet)
serializers.py:
class UserProfileCreateSerializer(serializers.ModelSerializer):
""""A serializer for user data request"""
location = serializers.CharField(source='profile.location')
friends_count = serializers.IntegerField(source='profile.friends_count',read_only=True)
profile_pic = serializers.FileField(source='profile.profile_pic',allow_empty_file=True,allow_null=True)
class Meta:
model = User
fields = (
'pk',
'username',
'email',
'password',
'location',
'friends_count',
'profile_pic',
)
extra_kwargs = {
'password':{'write_only':True},
'friends_count':{'read_only':True},
}
def create(self, validated_data):
""""Create and return a new User"""
user = User(
email = validated_data['email'],
username = validated_data['username']
)
user.set_password(validated_data['password'])
user.save()
return user

Adding an extra field in a ModelSerializer is not working

serializers.py:
from rest_framework import serializers
from django.utils.translation import ugettext_lazy as _
import models
class ExtensibleModelSerializerOptions(serializers.Serializer):
def __init__(self, meta):
super(ExtensibleModelSerializerOptions, self).__init__(meta)
self.model = getattr(meta, 'model', None)
self.read_only_fields = getattr(meta, 'read_only_fields', ())
self.non_native_fields = getattr(meta, 'non_native_fields',())
class ExtensibleModelSerializer(serializers.ModelSerializerOptions):
_options_class = ExtensibleModelSerializerOptions
def restore_object(self, attrs, instance=None):
for field in self.opts.non_native_fields:
attrs.pop(field)
return super(ExtensibleModelSerializer, self).restore_object(attrs, instance)
def to_native(self, obj):
ret = self._dict_class()
ret.fields = {}
for field_name, field in self.fields.items():
# --- BEGIN EDIT --- #
if field_name in self.opts.non_native_fields:
continue
# --- END --- #
field.initialize(parent=self, field_name=field_name)
key = self.get_field_key(field_name)
value = field.field_to_native(obj, field_name)
ret[key] = value
ret.fields[key] = field
return ret
class OptiUserSerializer(ExtensibleModelSerializer):
password_confirmation = serializers.CharField(max_length=models.OptiUser._meta.get_field('password').max_length)
company_id = serializers.PrimaryKeyRelatedField(queryset=models.Company.objects.all(), many=False)
password = serializers.CharField(
style={'input_type': 'password'}
)
def validate_password_confirmation(self, attrs, source):
password_confirmation = attrs[source]
password = attrs['password']
if password_confirmation != password:
raise serializers.ValidationError(_('Password confirmation mismatch'))
return attrs
class Meta:
model = models.OptiUser
fields = ('id', 'username', 'company_id', 'first_name', 'last_name', 'is_active', 'is_admin', 'password', 'password_confirmation',)
non_native_fields = ('password_confirmation',)
I'm having a customized User model for my app. I'm creating web a web service using DRF. I'm trying to make a user registration serializer as specified above. Everything is working fine except when I add 'password_confirmation' field it raises exception "model_name" object has no attribute password_confirmation". I found a code snippet as above which I'm trying to use above. But unfortunately it doesn't seems to be much helpful.
My question is that, Is it possible to add such a field and perform some comparisons on it. Is there any elegant way to do it?
Please suggest a fix.
Thanks! in Advance.
I don't think you need ExtensibleModelSerializer. Set the field to write_only:
password_confirmation = serializers.CharField(write_only=True, ...)

python-social not saving response to custom model

Ive been running into a number of problem in relation to using django's custom model. This one in particular is not raising any errors. For some reason after authenticating via steam and returning to the landing page the database tables for both steamuser_user (custom user) and social_auth_usersocialauth are empty. Nothing is being saved, no errors are being displayed etc.
My custom model which is quite similar to the one on django docs official page is as follows:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import BaseUserManager
# Create your models here.
class UserManager(BaseUserManager):
def create_user(self, steamid, username, password=None):
if not steamid:
msg = 'User has no Steam ID set'
raise ValueError(msg)
if not username:
msg = 'User has no name set'
raise ValueError(msg)
user = self.model(steamid=steamid,
username=username)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, steamid, username, password):
super_user = self.create_user(steamid=steamid,
username=username,
password=password)
super_user.is_staff = True
super_user.is_admin = True
super_user.is_mod = True
super_user.save(using=self._db)
return super_user
class User(AbstractBaseUser):
steamid = models.CharField(max_length=20, unique=True)
username = models.CharField(max_length=80)
email = models.EmailField(null=True,blank=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
is_mod = models.BooleanField(default=False)
date_joined = models.DateTimeField(auto_now_add=True)
reputation = models.IntegerField(max_length=6, default=0)
USERNAME_FIELD = 'steamid'
objects = UserManager()
def __unicode__(self):
return self.username
def get_full_name(self):
return self.steamid
def get_short_name(self):
return self.username
The settings I've used are as follows:
SOCIAL_AUTH_USER_MODEL = 'steamuser.User'
AUTH_USER_MODEL = 'steamuser.User'
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
'social.apps.django_app.context_processors.backends',
'social.apps.django_app.context_processors.login_redirect',
)
AUTHENTICATION_BACKENDS = (
'social.backends.steam.SteamOpenId',
'django.contrib.auth.backends.ModelBackend',
)
#Steam OpenAuth
SOCIAL_AUTH_STEAM_API_KEY = 'B1D7C629D093D4B72577F2F11DE4EBE2'
LOGIN_URL = '/'
SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/'
SOCIAL_AUTH_ENABLED_BACKENDS = (
'steam',
)
Any help would be appreciated!
EDIT
Backends steam.py
def get_user_details(self, response):
player = self.get_json(USER_INFO, params={
'key': self.setting('API_KEY'),
'steamids': self._user_id(response)
})
if len(player['response']['players']) > 0:
player = player['response']['players'][0]
details = {'steamid': player.get('steamid'),
'username': player.get('personaname'),
}
else:
details = {}
return details
EDIT 2
Well despite my logical reasoning, I just gave up and created a custom pipeline to create the new steam user as follows:
from django.contrib.auth import get_user_model
def create_steamuser(details, user=None, *args, **kwargs):
if user:
return {'is_new': False}
if not details:
return
try:
steam_user = get_user_model().objects.get(steamid=details['steamid'])
except steam_user.DoesNotExist:
get_user_model().objects.create_user(details['steamid'], details['username'])
return {
'is_new': True,
}
Now I still have the problem where social_user is not being created. I've set the social user model to use my new custom model but there must be something that I am missing.
python-social-auth won't be able to pass the steamid and date_joined parameters to your custom create_user() method in the manager. To make that possible you have three options:
Set =None to those parameters and set some default vaules for them
Override the default create_user pipeline and pass the extra parameters.
Add a custom pipeline function before create_user and fill details with steamid and date_joined, then define SOCIAL_AUTH_STEAM_USER_FIELDS = ('username', 'email', 'steamid', 'date_joined').