Tried to change primary key of id to a UUID field but is not working

Hi, so I am following the book Django for Professionals and trying to create a bookstore website. In chapter 11, he says to change the model of a Book to instead use a UUID. I had already setup Mysql as the database and migrated changes and everything beforehand. I think the main reason is because I have already migrated and made those tables, and now I am trying to change something fundamental like the primary key id.
This is the previous model of Book:

from django.db import models
class Book(models.Model):
      title = models.CharField(max_length=200)
      author = models.CharField(max_length=200)
      price = models.DecimalField(max_digits=6, decimal_places=2)
      def __str__(self):
                 return self.title

And this is the new one:

import uuid # new
from django.db import models
from django.urls import reverse
class Book(models.Model):
            id = models.UUIDField( # new
            primary_key=True,
            default=uuid.uuid4,
            editable=False)
            title = models.CharField(max_length=200)
            author = models.CharField(max_length=200)
            price = models.DecimalField(max_digits=6, decimal_places=2)
            def __str__(self):
                   return self.title
            def get_absolute_url(self):
                   return reverse("book_detail", args=[str(self.id)])

When I migrated the old model of Book, I think it conflicted with the new model of Book which uses the UUID but I’m not sure.
Now when I go to http://127.0.0.1:8000/books/, it gives me a AttributeError at /books/ 'int' object has no attribute 'replace'
This is also the error it gives me

Would really appreciate any help.

What changes did you make to your urls.py file for this modification? (Specifically, what does your new version of the url for book_detail look like?)

This is the new urls.py file

from django.urls import path
from .views import BookListView, BookDetailView

urlpatterns = [
    path("", BookListView.as_view(), name="book_list"),
    path("<uuid:pk>", BookDetailView.as_view(), name="book_detail"), # new
]
1 Like

I believe you are correct in that this change will affect new data being stored, but does not change instances of Book that are already in the database. I would suggest emptying that model and re-entering the data for it.

Yes, I am trying to empty the pages_book table but it is not working for some reason. I am trying to use python manage.py dbshell but it says CommandError: You appear not to have the ‘mysql’ program installed or on your path.

You could also try using the Django admin to delete the data.

Or you can do whatever you need to do for your operating system to install the mysql client program. (You should have some direct means of accessing your database anyway - it’s one of those tools you should always have available to you when necessary. How did you create your current database and user without it?)

Yes I used the mysql command line to create the database but when I look at the tables I cannot see pages_book

Tables 
 accounts_customuser                  |
| accounts_customuser_groups           |
| accounts_customuser_user_permissions |
| auth_group                           |
| auth_group_permissions               |
| auth_permission                      |
| django_admin_log                     |
| django_content_type                  |
| django_migrations                    |
| django_session                       |

What does the DATABASES section of your settings.py file look like?

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'bookstore',
        'USER': 'root',  
        'PASSWORD': 'PASSWORD',  
        'HOST': '127.0.0.1',  
        'PORT': '3306',  
    }
}

Ah, I was querying the wrong database, I was querying books while the actual name was bookstore. Extremely sorry, I will try and solve the problem now! Thank you for your help!

1 Like