Подтвердить что ты не робот

Может ли generic.GenericForeignKey() быть нулевым?

Я создаю объект, который отслеживает изменения (Обновления) в отношении создания, обновления и удаления других так называемых UUIDSyncable объектов в базе данных.

Это включает в себя любой объект, который расширяет методы UUIDSyncable classes save() и delete(), которые переопределяются, таким образом, что он создает новый объект Update, который регистрирует действие (вставлять, обновлять или удалять) и первоначально поле models.CharField(max_length=64), определяющее UUID pk из объектов UUIDSyncable.

На этом этапе я хотел обновить реализацию, чтобы использовать поле Django generic.GenericForeignKey() вместо моего единственного символьного поля. Это позволит получить доступ к объекту, о котором обновление записывается гораздо проще.

Моя проблема возникает, когда вы хотите удалить объект и сохранить его как объект Update, поскольку вы знаете, что Django создает каскадное удаление объекта UUIDSyncable, удаляя все предыдущие записи Update (которые не требуется).

Когда объект UUIDSyncable был удален в моей первоначальной реализации, каждый объект Update все равно сохранит UUID, чтобы информировать внешние стороны об его удалении. Моим первым решением эмулировать это было установить content_object = None непосредственно перед удалением объекта на всех объектах Update, тем самым предотвращая каскад удаления.

Это означает, что generic.GenericForeignKey() нельзя установить для значений NULL. Есть ли способ сделать это, или если не так, как стандартный CharField, содержащий первичный ключ UUID, и sperate CharField, содержащий имя модели, будет использоваться аналогичным образом?

4b9b3361

Ответ 1

Возможно, вам нужно установить null = True в базовые поля content_type и object_id, которые составляют общий внешний ключ.

Ответ 2

Для ленивых/прагматических:

class MyModel(models.Model):
    ...other fields...
    content_type = models.ForeignKey(ContentType, blank=True, null=True, on_delete=models.SET_NULL)
    object_id = models.PositiveIntegerField(blank=True, null=True)
    content_object = generic.GenericForeignKey('content_type', 'object_id')

Ответ 3

Что сказал Даниэль Роземан. Просто убедитесь, что вы обновляете свою базу данных, чтобы разрешить Null в этих полях, поскольку вы, возможно, создали таблицу, не установив ее.

Ответ 4

Вы пытались установить null=True на GenericForeignKey? Общие внешние ключи не являются концепцией, которая распознается низкоуровневым приложением базы данных (т.е. MySQL, SQLite и т.д.), Поэтому вы должны указать, что это поле должно быть нулевым.

null=True в поле базы данных в Django означает, что поле базы данных, представляющее эти данные, может быть пустым, тогда как blank=True сообщает о проверке формы/модели Django о том, что это поле ОК, оставленное пользователем пользователем ( или вы, через интерфейс администратора). Поэтому вам может понадобиться использовать оба варианта, чтобы добиться того, что вам нужно.