I followed the instructions from the Wagtail site for adding Wagtail to an existing Django project. At the end of the instructions, it said:
Note that there’s one small difference when not using the Wagtail project template: Wagtail creates an initial homepage of the basic type Page, which does not include any content fields beyond the title. You’ll probably want to replace this with your own HomePage class - when you do so, ensure that you set up a site record (under Settings / Sites in the Wagtail admin) to point to the new homepage.
I would like to change the 'basic type Page' to my model class BlogIndex. I know I can add the BlogIndex as a subpage of the default one and then point to it as described in the instructions. Instead, I would like to change the existing page. It bugs me having an unused page at the root. It would be a cleaner approach just to use it.
After adding my new class and migrating it, the django_content_type table looked like this:
1,admin,logentry
2,auth,permission
3,auth,group
4,auth,user
5,contenttypes,contenttype
6,sessions,session
7,wagtailcore,page
8,wagtailadmin,admin
9,wagtaildocs,document
10,wagtailimages,image
11,wagtailforms,formsubmission
12,wagtailredirects,redirect
13,wagtailembeds,embed
14,wagtailusers,userprofile
15,wagtailimages,rendition
16,wagtailimages,uploadedimage
17,wagtailsearch,query
18,wagtailsearch,querydailyhits
19,wagtailcore,grouppagepermission
20,wagtailcore,pagerevision
21,wagtailcore,pageviewrestriction
22,wagtailcore,site
23,wagtailcore,collection
24,wagtailcore,groupcollectionpermission
25,wagtailcore,collectionviewrestriction
26,taggit,tag
27,taggit,taggeditem
28,blog,blogindex
There is another table: wagtailcore_pages that contains three rows:
1,0001,1,1,Root,root,true,false,/,"",false,"",,,false,7
3,000100010001,3,0,Blog Index,blog-index,true,false,/blog/blog-index/,"",false,"",,,false,28
2,00010001,2,1,Welcome to your new Wagtail site!,home,true,false,/blog/,"",false,"",,,false,7
The last column is the content_type_id, which maps to the table above. I tried changing the value from 7 to 28. When I went to access the page in Wagtail admin, I got the error:
DoesNotExist at /cms/pages/2/
BlogIndex matching query does not exist.
Request Method: GET
Request URL: http://localhost:8006/cms/pages/2/
Django Version: 3.0.7
Exception Type: DoesNotExist
Exception Value:
BlogIndex matching query does not exist.
Exception Location: /Users/curt/htdocs/zetcho/venv/lib/python3.8/site-packages/django/db/models/query.py in get, line 415
Python Executable: /Users/curt/htdocs/zetcho/venv/bin/python
Python Version: 3.8.2
This happened before and after I added the the BlogIndex page that you see in the wagtailcore_pages. Both were after I ran the migration to add it to the model. When I change it back to 7, everything is back to normal. My guess is that it's looking for the model in the wrong place.
I then created a standalone Wagtail app to see how it was different. The start of django_content_type table looked like this:
1,wagtailcore,page
2,home,homepage
3,wagtailadmin,admin
The app_label 'home' is the name of the app that the wagtail process created. The home app has a model file with a HomePage class in it.
The wagtailcore_pages for the stand alone app contains two rows:
1,0001,1,1,Root,root,1,0,/,"",0,"",,,0,1
3,00010001,2,0,Home,home,1,0,/home/,"",0,"",,,0,2
It's interesting that the id for the second row is 3 (the first column is id). Given the field is auto increment, a row with the id 2 must have been added and then deleted. The only thing I did after the migration to do runserver to insure it worked.
Clearly, I'm missing another step or two to get it to work assuming that's even possible. Any idea what they might be?
There's a two or three year old ticket on the Wagtail site regarding the setting of the default page, but on solution.
Update
I attempted what I understood to be @gasman's solution. The wagtail_core_page now looks like this:
1,0001,1,1,Root,root,true,false,/,"",false,"",,,false,7
5,000100010001,3,0,Blog Index,blog-index,true,false,/blog/blog-index/,"",false,"",,,false,28
2,00010001,2,1,Welcome to your new Wagtail site!,home,true,false,/blog/,"",false,"",,,false,28
The only change here is setting the page type for the second row to 28. I also changed the blog_blogindex table to this:
2,<p>Introduction</p>
The first column had been five. I've added and deleted a few times, thus the five. I stopped and restarted the application and got the following error when I added /cms to the url:
KeyError at /cms/
5
Request Method: GET
Request URL: http://localhost:8006/cms/
Django Version: 3.0.7
Exception Type: KeyError
Exception Value:
5
Exception Location: /Users/curt/htdocs/zetcho/venv/lib/python3.8/site-packages/wagtail/core/query.py in specific_iterator, line 403
Python Executable: /Users/curt/htdocs/zetcho/venv/bin/python
Python Version: 3.8.2
My guess is because I still have the third row in the wagtail_core table above. I had that row in order to get a row to appear in the blog_blogindex table. I next tried to delete the row with the five in it and got a postgre/SQL error:
[23503] ERROR: update or delete on table "wagtailcore_page" violates foreign key constraint "wagtailcore_pagerevi_page_id_d421cc1d_fk_wagtailco" on table "wagtailcore_pagerevision" Detail: Key (id)=(5) is still referenced from table "wagtailcore_pagerevision".
After realizing I misread @gasman's clearly worded response, I added a second row to blog_blogindex:
5,<p>Introduction</p>
2,<p>unused page</p>
There only needs to be the one entry: the second one. I changed the seven to 28 in the wogtailcore_page for the row created as part of the setup. Wagtail ran without errors and the default page is using the BlogIndex class.
I had an additional problem: the site row was deleted. I'm pretty sure that was a result of me deleting the page to which it was pointing. I had changed the default home page in settings. I just added the row back and I was good. I should have changed the site row back first.
The Fix
- Add Wagtail to your project following the Wagtail instructions
- Add a model class for the home/base page you wish to use. I set mine up in a separate app.
- Run makemigrations and migrate.
- You should back up your database at this point in case things go horribly wrong in the next steps. You will be manually changing table data.
- Access the database and add the row to the new created class table as described by @gasman.
- Change the content_type_id column in wagtailcore_page of the second row to the id of the newly create class. There should only be two rows with the first one being the root. You can find the id in the django_content_type table.
- Commit your changes and run your app.