Я создаю REST API с помощью Django Rest Framework и Django Rest Auth.
У моих пользователей есть профиль потребителя.
class UserConsumerProfile(
SoftDeletableModel,
TimeStampedModel,
UniversallyUniqueIdentifiable,
Userable,
models.Model
):
def __str__(self):
return f'{self.user.email} ({str(self.uuid)})'
Как видите, он состоит из нескольких миксинов, которые дают ему UUID, отметку времени и обновленное поле, а также отношение OneToOne к пользователю.Я использую этот профайл потребителя в отношениях для связи данных с пользователем.
Этот профиль потребителя должен быть создан, как только пользователь зарегистрируется.
Вот сериализатор, который я написал для регистрации:
from profiles.models import UserConsumerProfile
from rest_auth.registration.serializers import RegisterSerializer
class CustomRegisterSerializer(RegisterSerializer):
def custom_signup(self, request, user):
profile = UserConsumerProfile.objects.create(user=user)
profile.save()
Я подключил этот сериализатор в настройках:
REST_AUTH_REGISTER_SERIALIZERS = {
"REGISTER_SERIALIZER": "accounts.api.serializers.CustomRegisterSerializer"
}
Он работает безупречно, когда пользователи регистрируются, используя его электронную почту.Но когда он регистрируется через Facebook, профиль потребителя не создается.
Я думал, что социальное представление также будет использовать сериализатор регистра при создании пользователей?Как запустить пользовательскую логику после регистрации в социальной сети?
РЕДАКТИРОВАТЬ для вознаграждения:
Вот настройки, которые я использую для Django Rest Auth:
# django-allauth configuration
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_CONFIRM_EMAIL_ON_GET = True
ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 1
ACCOUNT_LOGOUT_ON_PASSWORD_CHANGE = True
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
ACCOUNT_ADAPTER = 'accounts.adapter.CustomAccountAdapter'
SOCIALACCOUNT_ADAPTER = 'accounts.adapter.CustomSocialAccountAdapter'
SOCIALACCOUNT_PROVIDERS = {
'facebook': {
'METHOD': 'oauth2',
'SCOPE': ['email', 'public_profile', 'user_friends'],
'AUTH_PARAMS': {'auth_type': 'reauthenticate'},
'INIT_PARAMS': {'cookie': True},
'FIELDS': [
'id',
'email',
'name',
'first_name',
'last_name',
'verified',
'locale',
'timezone',
'link',
'gender',
'updated_time',
],
'EXCHANGE_TOKEN': True,
'LOCALE_FUNC': 'path.to.callable',
'VERIFIED_EMAIL': True,
'VERSION': 'v2.12',
}
}
# django-rest-auth configuration
REST_SESSION_LOGIN = False
OLD_PASSWORD_FIELD_ENABLED = True
REST_AUTH_SERIALIZERS = {
"TOKEN_SERIALIZER": "accounts.api.serializers.TokenSerializer",
"USER_DETAILS_SERIALIZER": "accounts.api.serializers.UserDetailSerializer",
}
REST_AUTH_REGISTER_SERIALIZERS = {
"REGISTER_SERIALIZER": "accounts.api.serializers.CustomRegisterSerializer"
}
А вот пользовательские адаптеры (на случай, если они имеют значение):
from allauth.account.adapter import DefaultAccountAdapter
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from allauth.utils import build_absolute_uri
from django.http import HttpResponseRedirect
from django.urls import reverse
class CustomAccountAdapter(DefaultAccountAdapter):
def get_email_confirmation_url(self, request, emailconfirmation):
"""Constructs the email confirmation (activation) url."""
url = reverse(
"accounts:account_confirm_email",
args=[emailconfirmation.key]
)
ret = build_absolute_uri(
request,
url
)
return ret
def get_email_confirmation_redirect_url(self, request):
"""
The URL to return to after successful e-mail confirmation.
"""
url = reverse(
"accounts:email_activation_done"
)
ret = build_absolute_uri(
request,
url
)
return ret
def respond_email_verification_sent(self, request, user):
return HttpResponseRedirect(
reverse('accounts:account_email_verification_sent')
)
class CustomSocialAccountAdapter(DefaultSocialAccountAdapter):
def get_connect_redirect_url(self, request, socialaccount):
"""
Returns the default URL to redirect to after successfully
connecting a social account.
"""
assert request.user.is_authenticated
url = reverse('accounts:socialaccount_connections')
return url
Наконец, вот мнения:
from allauth.socialaccount.providers.facebook.views import \
FacebookOAuth2Adapter
from rest_auth.registration.views import SocialConnectView, SocialLoginView
class FacebookLogin(SocialLoginView):
adapter_class = FacebookOAuth2Adapter
class FacebookConnect(SocialConnectView):
adapter_class = FacebookOAuth2Adapter
Я думал , что если бы я подключил сериализатор, как я это делал в начальной части вопроса, логика сериализатора регистра также запустится, когда кто-то зарегистрируется с помощью facebook.
Что мне нужно сделать, чтобы эта логика такжезапускать, когда кто-то регистрируется с помощью Facebook?
(Если я не могу это исправить, я могу сделать второй запрос к серверу после каждой регистрации на Facebook на стороне клиента, который создает userconsumerprofile, но это будет своего рода излишними введет новую поверхность кода, которая приведет к более высокой вероятности ошибок.)