更新 カスタムマネージャーのすべてを次のように置き換えてみました。
def create_user(self, username, email):
return self.model._default_manager.create(username=username)
そして、それはエラーをスローします。次に、カスタムユーザーマネージャーからユーザーを返そうとすると、「割り当てられません」が表示されます。「UserSocialAuth.user」は「Barbuser」インスタンスである必要があります。associate_userからスローされます。それはdjango.db.models.fields.related.pyの腸から来ています。基本的に、カスタムモデルマネージャーからユーザーを正しく作成する方法を知ることに固執しています。私はドキュメントから直接離れていたので、ModelManagerに組み込まれているdjangoからすべてをコピーすることになりました。ヘルプ? アップデート
django-social-authの設定に問題があります。私はこれに3〜4日間いて、タオルを投げる準備をしています。動作する既存のユーザー登録アプリをインストールしてから、django-social-authgithubサイトのドキュメントをインストールしてフォローしました。私はsettings.pyに以下を追加しました
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
# Uncomment the next line to enable the admin:
'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
'polls',
'barbuser',
'social_auth',
)
AUTHENTICATION_BACKENDS = (
'social_auth.backends.facebook.FacebookBackend',
'django.contrib.auth.backends.ModelBackend',
)
FACEBOOK_APP_ID = os.environ.get('FACEBOOK_APP_ID')
FACEBOOK_API_SECRET = os.environ.get('FACEBOOK_SECRET')
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'social_auth.context_processors.social_auth_by_type_backends',
)
#SOCIAL_AUTH_ENABLED_BACKENDS = ('facebook',)
SOCIAL_AUTH_DEFAULT_USERNAME = 'new_social_auth_user'
LOGIN_URL = '/login/'
LOGIN_REDIRECT_URL = '/profile/'
LOGIN_ERROR_URL = '/login-error/'
SOCIAL_AUTH_USER_MODEL = 'barbuser.Barbuser'
私のmodels.pyは次のようになります:
from datetime import date
from django.db import models
from django.contrib.auth.models import User
from django.db.models import BooleanField
from django.db.models.fields import DateTimeField
from django.utils import timezone
from django.utils.crypto import get_random_string
class BarbuserManager(models.Manager):
@classmethod
def normalize_email(cls, email):
"""
Normalize the address by converting the domain part of the email address to lowercase.
"""
email = email or ''
try:
email_name, domain_part = email.strip().rsplit('@', 1)
except ValueError:
pass
else:
email = '@'.join([email_name, domain_part.lower()])
return email
def create_user(self, username, email=None, password=None):
"""
Creates and saves a User with the given username, email and password.
"""
email = 'you@email.com' if email.strip() == '' else email
now = timezone.now()
if not username:
raise ValueError('The given username must be set')
email = BarbuserManager.normalize_email(email)
user = User(username=username, email=email,
is_staff=False, is_active=True, is_superuser=False,
last_login=now, date_joined=now)
user.set_password(password)
user.save()
barbuser = Barbuser(user=user, birthday=date.today(), last_login=user.last_login, name=username)
barbuser.save()
return barbuser
def create_superuser(self, username, email, password):
u = self.create_user(username, email, password)
u.is_staff = True
u.is_active = True
u.is_superuser = True
u.save(using=self._db)
return u
def make_random_password(self, length=10,
allowed_chars='abcdefghjkmnpqrstuvwxyz'
'ABCDEFGHJKLMNPQRSTUVWXYZ'
'23456789'):
""" Generates a random password with the given length and given allowed_chars. Note that the default value of allowed_chars does not have "I" or "O" or letters and digits that look similar -- just to avoid confusion. """
return get_random_string(length, allowed_chars)
def get_by_natural_key(self, username):
return self.get(username=username)
class Barbuser(models.Model):
user = models.OneToOneField(User)
username = models.CharField(max_length=200)
last_login = DateTimeField(blank=True)
is_active = BooleanField(default=True)
birthday = models.DateField()
name = models.CharField(max_length=200)
objects = BarbuserManager()
def __init__(self, *args, **kwargs):
me = super(Barbuser, self).__init__(*args, **kwargs)
barbuser = me
return me
def __unicode__(self):
return self.name
def is_authenticated(self):
return self.user.is_authenticated()
urls.pyを更新して「social_auth.urls」を含めました。認証後、ユーザーはviews.pyからViewProfileビューにリダイレクトされます。
# Create your views here.
from barbuser.forms import RegistrationForm, LoginForm
from barbuser.models import Barbuser
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template.context import RequestContext
def create_Barbuser(form):
user = User.objects.create_user(form.cleaned_data['username'], form.cleaned_data['email'], form.cleaned_data['password'])
user.save()
barbuser = Barbuser(user=user, name=form.cleaned_data['name'], birthday=form.cleaned_data['birthday'])
barbuser.save()
def process_form(form, request_context):
if form.is_valid():
create_Barbuser(form)
return HttpResponseRedirect('/profile/')
else:
return render_to_response('register.html', {'form': form}, context_instance=request_context)
def render_blank_registration_form(request):
'''When the user is not submitting the form, show them the blank registration form.'''
form = RegistrationForm()
context = {'form': form}
return render_to_response('register.html', context, context_instance=RequestContext(request))
def BarbuserRegistration(request):
"""
Handles the registration of new Barbwire users.
"""
if request.user.is_authenticated():
return HttpResponseRedirect('/profile/')
if request.method == "POST":
return process_form(RegistrationForm(request.POST), RequestContext(request))
else:
return render_blank_registration_form(request)
def LoginRequest(request):
'''
Handles Login requests.
'''
if request.user.is_authenticated():
return HttpResponseRedirect('/profile/')
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
barbuser = authenticate(username=username, password=password)
if barbuser is not None:
login(request, barbuser)
return HttpResponseRedirect('/profile/')
else:
return render_to_response('login.html', {'form' : form}, context_instance=RequestContext(request))
else:
return render_to_response('login.html', {'form' : form}, context_instance=RequestContext(request))
else:
form = LoginForm()
return render_to_response('login.html', {'form' : form}, context_instance=RequestContext(request))
def LoginError(request):
return render_to_response('login.html', {'form' : LoginForm()}, context_instance=RequestContext(request))
def LogoutRequest(request):
logout(request)
return HttpResponseRedirect('/')
def ViewProfile(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/login/')
else:
return render_to_response('profile.html',{'barbuser' : request.user.barbuser }, context_instance=RequestContext(request))
私の問題は2つあります。この余分なものをmodels.pyに追加すると、次のようになります。
def facebook_extra_values(sender, user, response, details, **kwargs):
return False
from social_auth.signals import pre_update
from social_auth.backends.facebook import FacebookBackend
pre_update.connect(facebook_extra_values, sender=FacebookBackend)
サーバーの起動時にエラーが発生します:assert isinstance(to、basestring)、 "%s(%r)is invalid。ForeignKeyの最初のパラメーターは、モデル、モデル名、または文字列%r"%(self .class ._ name _、to、RECURSIVE_RELATIONSHIP_CONSTANT)AssertionError:ForeignKey(None)が無効です。ForeignKeyの最初のパラメーターは、モデル、モデル名、または文字列「self」のいずれかである必要があります
それを削除すると、Facebookフローでログインを通過できますが、次のようになります。/ complete /facebook/のAttributeError'NoneType'オブジェクトには属性'extra_data'がありません
何が欠けているのか、どこが間違っているのかわかりません。誰かが私がどこで間違っているのか説明するのを手伝ってもらえますか?
更新 デバッグで問題を追跡しましたが、「UserSocialAuth.objects.create」を試行すると、associate_user関数のsocial_auth.backends.pipeline.social.pyでIntegrityErrorが発生しているようです。次に、social_auth_user()を呼び出すExceptブロックにフォールバックし、この関数はsocial_userに対してNoneを返します。私が得ているIntegrityErrorは次のとおりです。
insert or update on table "social_auth_usersocialauth" violates foreign key constraint "social_auth_usersocialauth_user_id_fkey"
DETAIL: Key (user_id)=(17) is not present in table "auth_user".
私は、social_userをmodels.pyのCustomUserManagerで作成されたユーザーに関連付ける方法、場所、または理由を十分に理解していません。また、facebook_extra_values、追加のインポート、preupdate.connectのものをmodels.pyの下部から削除しました。これは、それが何をするのか、何のためにあるのかが本当にわからないためです。関連付けが欠落しているという最初の問題を修正しようとして、サンプルアプリから物事をコピーしただけでした。ヘルプ? アップデート