1

Getting an attribute error at a model in django. When I tried to call the model.get_absolute_url at my model_list templates.it says model has no attributen "id" while in the model,i ve also written both the url mapper and the view function correctly,including the detals templates the exception was pointing to this reverse line This is the the model in models.py file

class Post(models.Model): 
    title=models.CharField(max_length=200,help_text="Write your title",primary_key=True)
    caption=models.TextField(help_text="Write something")
    image=models.FileField(blank=True)
    post_date=models.DateField(auto_now=True)
    class Meta:
        ordering=['post_date']
    def __str__(self):
        return self.title
    def __str__(self):
        return self.caption
    def get_absolute_url(self):
        return reverse('post-detail', args=[str(self.id)])

#here is the url path

urlpatterns +=[
    path('posts',views.PostListView.as_view(),name="post-list"),
    path('post/<int:pk>',views.PostDetailView.as_view(),name="post-detail")
    ]
  • Share the relevant model and the URL path. – Willem Van Onsem Jan 15 '22 at 22:27
  • i have edited the post,it now contains both the models and the url path – Prince Godswill Jan 15 '22 at 22:37
  • By making `title` the primary key, Django will not add an `id` as primary key, that is only the case if you do not specify a primary key yourself, so there is no `.id` field in your model, and the primary key is now a `str`ing, no longer an `int`. – Willem Van Onsem Jan 15 '22 at 22:46
  • so how do i resolve this,by setting the title primary key to False? – Prince Godswill Jan 15 '22 at 22:59
  • after removing the primary key from the title ,this is the response i got from the terminal on makemigrations request * $ python manage.py makemigrations You are trying to add a non-nullable field 'id' to post without a default; we can't do that (the database needs something to populate existing rows). Please select a fix: 1) Provide a one-off default now (will be set on all existing rows with a null value for this column) 2) Quit, and let me add a default in models.py Select an option:* – Prince Godswill Jan 15 '22 at 23:06

1 Answers1

0

Expanding on Willem Van Onsem's comment, rewrite the model as you already did, from your last comment,

class Post(models.Model): 
    title=models.CharField(max_length=200,help_text="Write your title")
    caption=models.TextField(help_text="Write something")
    image=models.FileField(blank=True)
    post_date=models.DateField(auto_now=True)
    class Meta:
        ordering=['post_date']
    def __str__(self):
        return self.title
    def __str__(self):
        return self.caption
    def get_absolute_url(self):
        return reverse('post-detail', args=[str(self.id)])

#here is the url path

urlpatterns +=[
    path('posts',views.PostListView.as_view(),name="post-list"),
    path('post/<int:pk>',views.PostDetailView.as_view(),name="post-detail")
    ]

Now to handle the error you get after doing this. If you're in development and have no data in your database that you need to keep you can drop and recreate the entire database and re run the commands:

    python manage.py makemigrations
    python manage.py migrate

or,

    python manage.py flush

Source: https://docs.djangoproject.com/en/4.0/ref/django-admin/#flush

But note that this will erase all the data from your database. If you need to keep the data, checkout the accepted answer by S. here:

Unload your data into JSON files. Use Django's own internal django-admin.py tools for this. You should create one unload file for each that will be changing and each table that depends on a key which is being created. Separate files make this slightly easier to do.

Drop the tables which you are going to change from the old schema.

Tables which depend on these tables will have their FK's changed; you can either update the rows in place or -- it might be simpler -- to delete and reinsert these rows, also.

Create the new schema. This will only create the tables which are changing.

Write scripts to read and reload the data with the new keys. These are short and very similar. Each script will use json.load() to read objects from the source file; you will then create your schema objects from the JSON tuple-line objects that were built for you. You can then insert them into the database.

You have two cases.

Tables with PK's change changed will be inserted and will get new PK's. These must be "cascaded" to other tables to assure that the other table's FK's get changed also.

Tables with FK's that change will have to locate the row in the foreign table and update their FK reference.

Alternative.

Rename all your old tables.

Create the entire new schema.

Write SQL to migrate all the data from old schema to new schema. This will have to cleverly reassign keys as it goes.

Drop the renamed old tables.

raphael
  • 2,469
  • 2
  • 7
  • 19