Reputation: 117
This is currently what I have in my models.py:
class Campaign(models.Model):
campaign_id = UUIDField(auto=True)
name = models.CharField("Campaign Name", max_length=255)
class CampaignResponse(models.Model):
campaign = models.ForeignKey(Campaign)
user = models.EmailField("Email", max_length=200)
response = models.TextField()
Recently I was thinking of changing the campaign_id in the Campaign model from UUIDField
to CharField
instead, but when I tried to do so, I noticed the data for campaign_id is being altered (e.g. the data was "7182c679f72844ca83c9648a120bb066"
when UUIDField
is being used, but it now becomes "7182c679-f728-44ca-83c9-648a120bb066"
after converting it to CharField
).
Is there some steps I have to follow where I can convert that UUIDField
to CharField
without changing the data and ensure the relationship between Campaign and CampaignResponse
is not broken?
Upvotes: 1
Views: 1397
Reputation: 7118
campaign_id is not the primary key for model Campaign. But probably it's for the best because now your relations can't break when you convert UUID to CharField.
First make campaign_id CharField
campaign_id = models.CharField(max_length=36, ) # add other stuff too which you want like unique etc.
About converting from uuid to str, open shell py manage.py shell
and run this:
from myApp.models import Campaign
for c in Campaign.objects.all():
c.campaign_id = str(c.campaign_id).replace('-', '')
Check your database to make sure it worked. Now you can decrease the max_length
of CharField to 32 since all the extra dash (-
) from campaign_id are gone.
Just because a Field is UUID doesn't means it's the primary key. To make a field primary key you need to pass primary_key=True
. You can make primary key like this
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
Upvotes: 2
Reputation: 616
The two commenters are correct, the UUID is not your primary key here. Any foreign keys relating to your campaign are holding the primary key (PK), which is just an auto-incrementing integer here.
Unfortunately it can sometimes be a pain to change primary keys for exactly the reason you're worried about. I've gone through this before, here's what I suggest:
Leave your primary keys as they are. It will ensure that you won't have any problems with relations. If you want a UUID field to be able to look up objects or pass around the reference without the potential issues caused by integer PKs. An example of such an issue would be if you're using a REST API, it would look weird if someone saw this link: GET /campaigns/6 <-- because they would know to just try GET /campaigns/7 and maybe they'd see something they weren't meant to see.
clearly GET /campaigns/7182c679-f728-44ca-83c9-648a120bb066 is better.
You can add unique=True to your UUID field to ensure django creates an index for it, then the performance wouldn't differ.
Does this answer you question?
Upvotes: 2