Экземпляры модели без значения первичного ключа невозможно хэшировать с помощью 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.

Прилагаются изображения, показывающие данные в Компас.

first second

Когда я не указывал _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)
Вернуться на верх