Reputation: 37
I am getting the error Model instances without primary key value are unhashable
when trying to remove a model instance from my admin panel.
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)
The issue lies with the EventPlatformDevice
model I believe. The issue I think is when I create a new entry in the Admin panel and setup the relationships between EventPlatformDevice.applicable_apps
it gets saved into the MongoDB using a _id:ObjectId("61c25d36cdca07c8a6101044")
since that is what Mongo uses. I changed all of my primary keys to use a UUID since that was the only way I could get it to work. Now I think it is having a issue that some of my items are using ObjectId
while some are using the _id:Binary('7w6NaYCQQn6BS7jaOXUNZw==', 3)
that I am getting from uuid.
Is it possible to define what type the _id
field is for everything? That way I can set it to use UUID.
Attached are images showing the data in Compass.
When I did not specify the _id
in all my models, I was getting errors when deleting and accessing. It was like Django did not know how to reference the ObjectId. That is why I went with UUID. But since I cannot control the dd.parsers_eventplatformdevice_applicable_apps
(2nd pic) it is having issues deleting it.
Upvotes: 1
Views: 1421
Reputation: 23
Is it possible to define what type the _id field is for everything?
I am afraid not. Each driver implementations may implement UUID serialization and deserialization logic differently, which may not be fully compatible with other drivers. (docs).
First, You can configure a UUID Representation, since PyMongo is using a legacy method to encode and decode UUID (0x03 subtype), you can change to cross-language compatible Binary 0x04 subtype. To do so in Djongo, just provide uuidRepresentation in the database settings as a standard (docs):
DATABASES = {
'default': {
'ENGINE': 'djongo',
'NAME': 'dd',
'ENFORCE_SCHEMA': False,
'CLIENT': {
'host': 'mongodb://localhost:27017',
'uuidRepresentation': 'standard',
'waitQueueTimeoutMS': 30000
},
},
}
Second, I would definitely try to make _id works. So the cration of the _id field will be provided by MongoDB server. If that does not work for you:
_id = models.ObjectIdField(primary_key=True)
then you could try this one:
_id = models.AutoField(auto_created=True, primary_key=True, unique=True)
Upvotes: 2