python-social-auth/social-app-django

Subclassing AbstractUserSocialAuth creates migration in social_django app.

Opened this issue · 1 comments

Expected behaviour

Subclass AbstractUserSocialAuth in my app and create a migration in my app folder.

Actual behaviour

A migration is created in social_django/migrations folder.

  • schema is a local application with an abstract model to compare the behavior.
  • AbstractUserSocialAuth requires to override the user attribute in order to avoid related_name collision` so:
  • I override the slug attribute in BaseSlug to be in par:

What are the steps to reproduce this issue?

Input clear steps to reproduce the issue for a maintainer.

  1. Install social-app-django as per the docs.
  2. people is the app with the custom user model.

people/models.py:

from django.contrib.auth.models import AbstractUser
from django.contrib.auth import get_user_model
from django.db import models
from social_django.models import AbstractUserSocialAuth
from schema.models import BaseSlug


class User(AbstractUser):
    pass


class Test(BaseSlug):
    slug = models.IntegerField(
        primary_key=True, db_index=True, verbose_name="Slug"
    )


class Test2(AbstractUserSocialAuth):
    user = models.ForeignKey(
        get_user_model(), related_name="people_social_auth", on_delete=models.CASCADE
    )
  1. ./manage.py makemigrations

Any logs, error output, etc?

Result:

Migrations for 'people':
  people/migrations/0002_test.py
    - Create model Test
Migrations for 'social_django':
  .venv/lib/python3.11/site-packages/social_django/migrations/0016_test2.py
    - Create model Test2

Any other comments?

  • Why is that?
  • What will happen if social_django also creates a migration no. 16?

I need to encrypt uid field and I am not sure that creating a migration in social_django app helps. Is this intended?

My solution is to create AbstractuserSocialAuth from scratch.

If this is intended, it would be nice to have the following methods to an InProjectMixin in order to avoid unnecessary code duplication.

@classmethod
def get_social_auth(cls, provider, uid):
try:
return cls.objects.select_related("user").get(provider=provider, uid=uid)
except cls.DoesNotExist:
return None
@classmethod
def username_max_length(cls):
username_field = cls.username_field()
field = cls.user_model()._meta.get_field(username_field)
return field.max_length
@classmethod
def user_model(cls):
return cls._meta.get_field("user").remote_field.model