I believe you either have a Python IDE or a code editor. I use Pycharm. Many people like VS Code. If you don't, go and download one before moving on.
Hoping you have a Code Editor now, open your project in your editor. You might want to get familiar with the files and folders in your project.
You might recognize the 'manage.py' file, as it was the one we used when we wanted to run the server. You should have a file named 'db.sqlite3'. This is the database file. It was automatically generated when we run the server. Other database services could be used - like Postgres, MySQL. However, we'd be working with the default. Later on, we could discuss setting up a Postgres Database.
There is the '__init__.py' which just identifies the 'awesome' directory as a group of python files, or what we can call a module. The 'settings.py' file contains the settings for our Django project. We'd be diving into it as we move on.
Then, we have 'urls.py' which contains the URLs that our site would make use of. If you view it now, you see some comment and then one 'urlpattern', which is:
urlpatterns = [ path('admin/', admin.site.urls), ]
If you run your server now, make sure your virtual environment is active. Remember, to run the server:
/awesome$ python manage.py runserver
And then visit 127.0.0.1:8000/admin, you should see a sign in page that looks like:
Lastly, we have the 'wsgi.py' file.
The Web Server Gateway Interface (WSGI) is a simple calling convention for web servers to forward requests to web applications or frameworks written in the Python programming language. From Wikipedia
In case you're curious, you would find extra information online. However, we won't be toying with this file much. I doubt we'd ever touch it.
Before moving forward, we'd be renaming the folder up-top to 'awesome-project' so as to differentiate it from the one that contains the 'urls.py' and other files.
The database is, well the database. Stores information, data and a whole bunch of things. The first task we would be performing with the database is creating a 'superuser'. A superuser has 'ultimate level access' to the entire project. Make sure you're careful with your superuser account. To create one, run:
/awesome-project$ python manage.py createsuperuser
If you do this at this point, you would get a bunch of errors. Well, that's because the database hasn't been prepared to receive the information. Django has a nice way of managing the databases with its migrations. If a change that should be reflected in the database is performed, Django requests you to 'makemigrations' and then 'migrate'. Unapplied migrations always show up. Similar to:
You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them.
To makemigrations, run:
/awesome-project$ python manage.py makemigrations
If changes are detected, it prepares it for migration.
To apply the migrations, run:
/awesome-project$ python manage.py migrate
You get something like:
Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying sessions.0001_initial... OK
This means you have successfully migrated your changes.
Now, try creating your superuser again
/awesome-project$ python manage.py createsuperuser Username: we-awesome Email address: email@example.com Password: DjangoPass Password (again): DjangoPass Superuser created successfully.
Note: I strongly advise you set a strong password. I'm only using this because it's for a tutorial. In real life projects. A strong password and a real email address are essential.
Now run your server again, visit the admin page via 127.0.0.1:8000/admin and login with your details.
One thing you should know is, you can change the link to the admin page. so if you want to change it from 127.0.0.1:8000/admin to 127.0.0.1:8000/some-random-text, just go the urls.py file and change it.
Visiting 127.0.0.1:8000/some-random-text opens the admin page; Visiting 127.0.0.1:8000/admin gives a 404 error
So what's the difference between a project and an app 🤔? Imagine a company with different teams. A marketing team, to well, market. A design team, you're on the development team. Your best friend is on the administration team and so on. Apps could be likened to the individual teams, while the project is like the company. We could create a 'blog' app to manage blogging issues. We could have a 'profile' app to manage user profiles and so on.
Let us create a 'blog' app.
To create an app. Open your terminal in the awesome-project directory. Make sure your virtual environment is active, then run:
/awesome-project$ django-admin startapp blog
As usual, you can give it another name.
I'm quite sure it worked✨✨! If not, 😟 review what you did and kindly tell me what went wrong.
Creating the app also creates a bunch of files that we haven't seen before.
As we move forward and encounter them, we'd discuss what they are.
We also need not forget to register the app in the settings.py file. (Actually, I forgot to register it as at the time of writing😬) To do this, open the apps.py file inside your 'blogs' directory and copy the name of the class. In my case, it is BlogConfig. Now go to settings.py. Scroll till you see INSTALLED_APPS. A number of apps are there by default, however, we want to add a new one which is BlogConfig. Add a Comma after the last line before the ']', move to the next line, and add:
blog - the name of the folder/app; apps - the name of the file; BlogConfig - the name of the class.
Please don't forget as I did.😬😬
The last thing we would consider in this lesson is how to change the default homepage. By this, I mean the page that shows up on visiting 127.0.0.1:8000. To do this, we need to create a template, an HTML file.
Let us use our blog app. Create a new folder inside the blog folder and name it 'templates'. You could create your HTML file directly into this folder or further add subdirectories to organize the files. Either way is fine. (Edit: As an example, I created a main-site subdirectory in the templates directory. And that would reflect in my views.py.)
You can see both the folder arrangement and the placement of the HTML file.
Now the question is: How do I get this file to display? This is where we visit the view.py file alongside urls.py.
This isn't everything that happens, but this is all we need for now. So let's follow the image. The user's request takes a plane 🛬 and lands in the 'urls.py' file. On getting there, it checks if the url exists. One thing you should know is our 'urls.py' file deals with only the suffix. i.e It doesn't include the 127.0.0.1:8000 in itself. So keeping that in mind, if we want to replace the default home page, we add one line to 'urls.py'.
20. urlpatterns = [ 21. path('some-random-text/', admin.site.urls), 22. path('',) 23. ]
The newly added line says when they input the prefix(127.0.0.1:8000) without any suffix, come to me. The second box in our image says we should run the specified function in views.py. Which means we have to create a function that returns something. And the question is what do we want to return? The HTML file. So let's go create our function. In views.py, create a function, name it. It takes in at least one argument, which we would name request. And then returns the render of the HTML document on the URL that was requested. I know it's sounding confusing. Get a pen and paper, draw the different sections and try linking them up. My function looks like:
4. def home(request): 5. return render(request, 'main-site/home.html')
The views automatically check the templates folder as the base directory of all HTML documents. Now to add the view to our url path, we first have to import it into the urls.py file. At the top of the file, add:
1. from blog import views
This imports views from the blog app
And in the url path we added earlier, add some extra information
20. urlpatterns = [ 21. path('some-random-text/', admin.site.urls), 22. path('', views.home) 23. ]
This invariably says that when you open the link; prefix with an empty suffix; run the function named home, which you would find in the views file.
It is also a good practice to give names to your url's, as you would be referencing them a lot in your HTML documents. To add a name:
20. urlpatterns = [ 21. path('some-random-text/', admin.site.urls), 22. path('', views.home, name='home') 23. ]
Save everything, and restart your server.
💃🕺🍾💃🕺🍾 I think we should celebrate. Go get yourself a bottle of whatever you like best, you've worked hard.
You could go over it by creating another app and another url, and so on. Be curious. You have everything to gain!
I'd also take a break🍟. We continue another time.
Project can be found here