Django с социальным аутентификатором: Прямое назначение на прямую сторону множества "многие ко многим" запрещено

При попытке аутентификации (создания) пользователя в Django я получаю следующую ошибку:

Direct assignment to the forward side of a many-to-many set is prohibited. Use gave_mangoes.set() instead.

Код:

models.py

...
from waters.models import Water

class User(AbstractUser):
    id = models.AutoField(primary_key=True)
    posts = models.ManyToManyField(Water) # MANY TO MANY FIELD CAUSING ERROR
...

oauth.py

from social_core.backends.oauth import BaseOAuth2

class <name>Oauth2(BaseOAuth2):
    name = "<name>"
    AUTHORIZATION_URL = "<url>"
    ACCESS_TOKEN_URL = "<url>"
    ACCESS_TOKEN_METHOD = "POST"
    EXTRA_DATA = [("refresh_token", "refresh_token", True), ("expires_in", "expires")]

    def get_scope(self):
        return ["read"]

    def get_user_details(self, response):
        profile = self.get_json("<url>", params={"access_token": response["access_token"]})
        return {
            "id": profile["id"],
            "username": profile["username"],
            ...
        }

    def get_user_id(self, details, response):
        return details["id"]

Я прочитал этот ответ , в котором рассматривается та же ошибка:

Вам необходимо сохранить корзину, прежде чем вы сможете добавить элементы в поле "многие ко многим".

Однако, поскольку я использую Python Social Auth, он создает пользователя в бэкенде, поэтому я не могу сохранить его и изменить поле позже. Как я могу исправить эту ошибку?

Я смог обойти ошибку, расширив конвейер социальной аутентификации (документация). Во-первых, я сделал метод для создания пользователя соответствующим образом, чтобы обойти ошибку (как указано в ответе, связанном с вопросом):

authentication/pipeline.py

from authentication.models import User

def create_user(backend, user, response, *args, **kwargs):
    u = User()
    for k, v in kwargs["details"].items():
        setattr(u, k, v)
    u.save()
    # Optionally update many to many field here

и поместил это перед методом create_user социального аута:

settings.py

...
SOCIAL_AUTH_PIPELINE = (
    "social_core.pipeline.social_auth.social_details",
    "social_core.pipeline.social_auth.social_uid",
    "social_core.pipeline.social_auth.auth_allowed",
    "social_core.pipeline.social_auth.social_user",
    "social_core.pipeline.social_auth.associate_by_email",
    "authentication.pipeline.create_user", #ADDED
    "social_core.pipeline.user.create_user",
    "social_core.pipeline.social_auth.associate_user",
    "social_core.pipeline.social_auth.load_extra_data",
)
...
Вернуться на верх