Each Answer to this Q is separated by one/two green lines.
I am trying to get unique IDs for my Django objects. In Django 1.8 they have the UUIDField. I am unsure how to use this field in order to generate unique IDs for each object in my model.
Here is what I have for the UUIDField
import uuid from django.db import models class MyUUIDModel(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) class Person(models.Model): ... unique_id = MyUUIDModel()
I can reproduce the id for the UUID model, but everytime I do I get the exact same id. For Example:
person = Person.objects.get(some_field = some_thing) id = person.unique_id.id
id then gives me the same id every time. What is wrong, how do I fix this?
I’m not sure why you’ve created a UUID model. You can add the uuid field directly to the Person model.
class Person(models.Model): unique_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
Each person should then have a unique id. If you wanted the uuid to be the primary key, you would do:
class Person(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
Your current code hasn’t added a field to the person. It has created a
MyUUIDModel instance when you do MyUUIDModel(), and saved it as a class attribute. It doesn’t make sense to do that, the
MyUUIDModel will be created each time the models.py loads. If you really wanted to use the MyUUIDModel, you could use a
ForeignKey. Then each person would link to a different MyUUIDModel instance.
class Person(models.Model): ... unique_id = models.ForeignKey(MyUUIDModel, unique=True)
However, as I said earlier, the easiest approach is to add the UUID field directly to the person.
You need to use the class you created as a subclass when declaring your Person model like this:
import uuid from django.db import models class MyUUIDModel(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) class Person(MyUUIDModel): ...
This way Person becomes a subclass of MyUUIDModel and will inherit its id field definition.
You can directly add the
id field as a
UUIDField in the
Person model. There is no need for a separate
I think you have confused it with the
MyUUIDModel used in the UUIDField example where the
id is a
UUIDField. You can just use the below code and it will use
import uuid from django.db import models class Person(models.Model): ... id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
EDIT: Actually I was wrong. It’s not possible yet to implement it as
DEFAULT_AUTO_FIELD as it has to inherit from
IntegerField. Here’s the ticket in the django project with feature request to make it possible. Once it’s resolved I’ll update my answer.
As of Django 3.2, if you want to use
uuid as a pk for all your models on a project-wide level, you don’t need a generic abstract model anymore. Just define
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
so something like this should work
DEFAULT_AUTO_FIELD = 'django.db.models.UUIDField'
Or even better, create your own field.
DEFAULT_AUTO_FIELD = 'project.common.models.CustomUUIDField'
Where you also define uuid type etc.
As seen in the docs, it can also be applied on an app level.
class MyAppConfig(AppConfig): default_auto_field = 'project.common.models.CustomUUIDField'
To use UUID in Django for a new model see Django Docs.
However, if you want to use it for the existing model (with unique=True) having data corresponding to it, you will not be able to do it directly by the above documentation. It will create migration errors.
To do it without losing the data follow all the steps carefully of this Django Documentation.
in model import uuid:
in class model use:
class Article(TimeStampedModel): uuid = models.UUIDField(editable=False, default=uuid.uuid4, unique=True) user = models.ForeignKey(User, on_delete=models.SET_NULL, related_name="articles", null=True) categories = models.ManyToManyField(ArticleCategory, blank=True) title = models.CharField(max_length=500, null=True, blank=True) body = RichTextUploadingField(config_name="portal_lobar_config") image = models.ImageField(upload_to='article_images/', null=True, blank=True) headline = models.BooleanField(default=True) tags = models.ManyToManyField(ArticleTag, blank=True) slug = AutoSlugField(max_length=500, populate_from='title', unique_with="created__month", null=True) published = models.BooleanField(default=False) published_at = models.DateTimeField(null=True, blank=True) def __str__(self): return self.title class Meta: ordering = ['-created']