Экземпляры модели без значения первичного ключа невозможно хэшировать с помощью Djongo
Я получаю ошибку Model instances without primary key value are unhashable
при попытке удалить экземпляр модели из моей панели администратора.
models.py
from djongo import models
import uuid
PROPERTY_CLASSES = (
("p1", "Video Property"),
("p2", "Page Property"),
("trait", "Context Trait"),
("custom", "Custom Property")
)
EVENT_TYPES = (
("video", "Video Event"),
("track", "Track Event"),
("page", "Page Event")
)
class Device(models.Model):
_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=255)
class Platform(models.Model):
_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=255)
app_name_possibilities = models.TextField(blank=True)
class EventPlatformDevice(models.Model):
_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = ""
event_field = models.ForeignKey('Event', on_delete=models.CASCADE)
applicable_apps = models.ManyToManyField('Platform', blank=True)
applicable_devices = models.ManyToManyField('Device', blank=True)
property_group = models.ManyToManyField('PropertyGroup', blank=True)
custom_properties = models.ManyToManyField('Property', blank=True)
class Event(models.Model):
_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=255, unique=True)
event_type = models.CharField(max_length=20, choices=EVENT_TYPES)
class PropertyGroup(models.Model):
_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=100)
applicable_properties = models.ManyToManyField('Property')
class Property(models.Model):
_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=255)
property_class = models.CharField(max_length=20, choices=PROPERTY_CLASSES)
format_example = models.TextField(blank=True)
notes = models.TextField(blank=True)
Проблема заключается в модели EventPlatformDevice
, как я полагаю. Я думаю, что проблема заключается в том, что когда я создаю новую запись в панели администратора и устанавливаю отношения между EventPlatformDevice.applicable_apps
, она сохраняется в MongoDB с помощью _id:ObjectId("61c25d36cdca07c8a6101044")
, поскольку именно это используется в Mongo. Я изменил все свои первичные ключи на использование UUID, поскольку это был единственный способ заставить их работать. Теперь я думаю, что проблема в том, что некоторые из моих элементов используют ObjectId
, а некоторые используют _id:Binary('7w6NaYCQQn6BS7jaOXUNZw==', 3)
, которые я получаю из uuid.
Возможно ли определить, какой тип поля _id
для всего? Таким образом, я могу установить его на использование UUID.
Прилагаются изображения, показывающие данные в Компас.
Когда я не указывал _id
во всех своих моделях, я получал ошибки при удалении и доступе. Это было похоже на то, что Django не знал, как ссылаться на ObjectId. Вот почему я выбрал UUID. Но поскольку я не могу контролировать dd.parsers_eventplatformdevice_applicable_apps
(2-й рисунок), возникают проблемы с его удалением.
Можно ли определить, какой тип имеет поле _id для всего?
Боюсь, что нет. Каждый драйвер может реализовывать логику сериализации и десериализации UUID по-разному, что может быть не полностью совместимо с другими драйверами. (docs).
Во-первых, вы можете настроить представление UUID, поскольку PyMongo использует устаревший метод кодирования и декодирования UUID (подтип 0x03), вы можете изменить его на совместимый с другими языками двоичный подтип 0x04. Чтобы сделать это в Djongo, просто укажите uuidRepresentation в настройках базы данных как стандарт (docs):
DATABASES = {
'default': {
'ENGINE': 'djongo',
'NAME': 'dd',
'ENFORCE_SCHEMA': False,
'CLIENT': {
'host': 'mongodb://localhost:27017',
'uuidRepresentation': 'standard',
'waitQueueTimeoutMS': 30000
},
},
}
Во-вторых, я бы определенно попытался сделать так, чтобы _id работало. То есть кратинг поля _id будет обеспечиваться сервером MongoDB. Если это не сработает для вас:
_id = models.ObjectIdField(primary_key=True)
тогда вы можете попробовать следующее:
_id = models.AutoField(auto_created=True, primary_key=True, unique=True)