ForeignKey для AnonymousUser - PullRequest
       1

ForeignKey для AnonymousUser

2 голосов
/ 03 марта 2020

Я хотел бы следовать этому руководству и избежать обнуляемого ForeignKey.

У меня есть ForeignKey для django модели пользователя.

Если я попытаюсь сохраняя request.user в экземпляре этой модели, я получаю эту ошибку:

ValueError: Cannot assign "<SimpleLazyObject: <django.contrib.auth.models.AnonymousUser>>":
 "MyModel.user" must be a "User" instance.

Я думаю, что возможно избежать схемы безусловных данных (обнуляемый внешний ключ).

Как я мог решить это?

Ответы [ 3 ]

5 голосов
/ 03 марта 2020

Эти рекомендации предполагают создание экземпляра пользователя, который отражает анонимного пользователя. В противном случае известен как значение дозорного. Вы должны будете отслеживать это через какой-то уникальный ключ, вероятно, имя пользователя. Затем убедитесь, что он существует, и никто другой на самом деле не создал пользователя с этим ключом, в противном случае вы столкнетесь с другими проблемами.

Однако из-за указанных выше проблем я не согласен с этими рекомендациями. Если ваша модель данных допускает необязательные отношения, то вам обязательно следует использовать значения NULL.

По поводу комментария:

Если в ваших данных нет значения NULL, то при обработке данных в исходном коде не будет исключения NullPointerException: -)

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

1 голос
/ 13 марта 2020

Эй, это моя первая попытка ответить на вопрос! Я новичок ie, но у меня недавно была похожая ошибка. Я полагаю, что это наивный вариант ответа Найджела222, который требует сделать это с миграцией, но, возможно, здесь есть что-то ценное для другого новичка ie, которому нужно более простое решение. Я был под влиянием ответа на этот пост Аймана Аль-Абси, который предполагает, что вам может понадобиться сослаться на этого пользователя по его автоматически сгенерированному первичному ключу.

По умолчанию request.user AnonymousUser, когда не аутентифицирован. Из сообщения об ошибке видно, что AnonymousUser нельзя использовать в качестве значения для вашего внешнего ключа в таблице User. Предлагаемое решение:

from django.contrib.auth.models import User
# Start by creating a user in your User table called something like anon in some kind of initialization method:
tempUser= User.objects.create_user(username="anon", email="none", first_name="none", last_name="none")
tempUser.save()
#when the user is unauthenticated, before calling a method that takes request as a parameter do:
if request.user.is_anonymous:
  anonUser = User.objects.get(username='anon')
  request.user=User.objects.get(id=anonUser.id)

Еще один комментарий для новичка ie. Я сделал свою собственную таблицу под названием User в models.py. Это стало запутанным. Мне пришлось импортировать его с псевдонимом: from .models import User as my_user_table Было бы лучше просто назвать его my_user_table для начала.

0 голосов
/ 10 марта 2020

Создайте специальный экземпляр User для этой цели. Лучше всего это сделать при миграции данных для модели, которая будет полагаться на возможность создания ForeignKey для этого специального объекта User. Когда вы развертываете свое приложение, запускаете makemigrations и migrate, оно создает специальные пользовательские объекты до того, как в БД появятся реальные пользователи.

Существует много подробностей о создании миграций данных здесь

Вот пример того, как некоторые объекты группы будут существовать на момент этой миграции для любого будущего развертывания.

# Generated by Django 2.2.8 on 2020-03-05 09:53

from django.db import migrations

def apply_migration(apps, schema_editor):

    Group = apps.get_model("auth", "Group")
    Group.objects.bulk_create(
        [Group(name="orderadmin"), 
         Group(name="production"),
         Group(name="shipping")]
    )

def revert_migration(apps, schema_editor):
    Group = apps.get_model("auth", "Group")
    Group.objects.filter(name__in=["orderadmin", "production", "shipping"]).delete()


class Migration(migrations.Migration):

    dependencies = [
        ('jobs', '0034_auto_20200303_1810'),
    ]

    operations = [
        migrations.RunPython(apply_migration, revert_migration)
    ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...