Ответ 1
Возможно, вам нужно установить null = True в базовые поля content_type
и object_id
, которые составляют общий внешний ключ.
Я создаю объект, который отслеживает изменения (Обновления) в отношении создания, обновления и удаления других так называемых 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
, содержащий имя модели, будет использоваться аналогичным образом?
Возможно, вам нужно установить null = True в базовые поля content_type
и object_id
, которые составляют общий внешний ключ.
Для ленивых/прагматических:
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')
Что сказал Даниэль Роземан. Просто убедитесь, что вы обновляете свою базу данных, чтобы разрешить Null в этих полях, поскольку вы, возможно, создали таблицу, не установив ее.
Вы пытались установить null=True
на GenericForeignKey
? Общие внешние ключи не являются концепцией, которая распознается низкоуровневым приложением базы данных (т.е. MySQL, SQLite и т.д.), Поэтому вы должны указать, что это поле должно быть нулевым.
null=True
в поле базы данных в Django означает, что поле базы данных, представляющее эти данные, может быть пустым, тогда как blank=True
сообщает о проверке формы/модели Django о том, что это поле ОК, оставленное пользователем пользователем ( или вы, через интерфейс администратора). Поэтому вам может понадобиться использовать оба варианта, чтобы добиться того, что вам нужно.