Meal Plan
+No meals have been prepared yet!
+ +diff --git a/docs/source/index.md b/docs/source/index.md index 25371b79..f0ebb005 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -2,14 +2,20 @@ ```{toctree} :caption: Basics -:maxdepth: 2 +:maxdepth: 3 :hidden: self getting-started installation -tutorials/beginner-tutorial +``` + +```{toctree} +:caption: Tutorials +:maxdepth: 3 +:hidden: +tutorials/intro ``` ```{toctree} diff --git a/docs/source/tutorials/intro.md b/docs/source/tutorials/intro.md new file mode 100644 index 00000000..68bc3cc2 --- /dev/null +++ b/docs/source/tutorials/intro.md @@ -0,0 +1,15 @@ +# Meal Plan Tutorial + +```{note} +This tutorial is intended to familiarize you with some basic concepts around Django Unicorn. If you have little to no prior experience with Django or other web frameworks, this is a good place to start. However, having basic knowledge of Python and web development concepts will prove helpful. +``` + +The goal of this tutorial is to develop a Meal Plan application. With Django Unicorn, you will be able to create "Meals" and add them without refreshing the page. You will also be able to search dynamically for saved Meals. + +```{toctree} +mealplan/django-app +mealplan/unicorn-functionality +mealplan/unicorn-advanced +mealplan/summary +mealplan/full-text-tutorial.md +``` \ No newline at end of file diff --git a/docs/source/tutorials/mealplan/django-app.md b/docs/source/tutorials/mealplan/django-app.md new file mode 100644 index 00000000..a2ec80e4 --- /dev/null +++ b/docs/source/tutorials/mealplan/django-app.md @@ -0,0 +1,381 @@ +# Building a Django App + +## Installation + +Note: You must have Python installed before starting. + +To start with, create a new directory in your terminal where you will build your project. Once you are in this new directory, create a virtual environment and then activate it. + +```shell +# Inside your project directory +> python -m venv .venv + +# activate environment (MacOs or Linux) +> source .venv/bin/activate +``` + +Now install Django and Django Unicorn. + +```shell +# This installs the Django web framework +> python -m pip install Django + +# This installs Django Unicorn +> python -m pip install django-unicorn +``` + +Now you're ready to create a new Django project. This command will populate your directory with your Django project files and directories. + +```shell +django-admin startproject app . +``` + +(Typing the period `.` in the end will ensure Django is created in your current directory. You can substitute `app` with any other name.) + +Once you have created your project, let's build your "Meal Plan" application. + +## Create Meal Plan App + +You should now have a basic project structure that looks a little like this: + +``` +my-project/ +┣ .venv/ +┣ mealplan/ +┃ ┣ asgi.py +┃ ┣ settings.py +┃ ┣ urls.py +┃ ┣ wsgi.py +┃ ┗ __init__.py +┗ manage.py +``` + +In order to create your Meal Plan application, make sure that you are in the `my-project` directory and type the following command. + +```shell +python manage.py startapp mealplan +``` + +In this case, `mealplan` is the name of your app. You can choose to name it something different if you prefer. + +After running the command, your file structure should look like this. + +``` +my-project/ +┣ .venv/ +┣ app/ +┃ ┣ asgi.py +┃ ┣ settings.py +┃ ┣ urls.py +┃ ┣ wsgi.py +┃ ┗ __init__.py +┣ mealplan/ +┃ ┣ migrations/ +┃ ┣ admin.py +┃ ┣ apps.py +┃ ┣ models.py +┃ ┣ tests.py +┃ ┣ views.py +┃ ┗ __init__.py +┗ manage.py +``` + +Next, we need to register your `mealplan` app, as well as `Django Unicorn` (which we installed earlier) into the `my-project/app/settings.py` file. + +Find the `INSTALLED_APPS` and include them like this: + +```python +# app/settings.py + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'django_unicorn', + 'mealplan', +] +``` + +## Creating Models + +We will use SQLite as a database for our meal plans. This setting already comes configured with Django, but we must first _create a migration_ which will allow us to use Models to represent the data in the database. + +Run the command `python manage.py migrate` and you should see something like this: + +```shell +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 auth.0012_alter_user_first_name_max_length... OK + Applying sessions.0001_initial... OK +``` + +So let's create a model for our meals. + +```python +# mealplan/models.py + +from django.db import models + +class Meal(models.Model): + TYPE_OF_MEAL = { + "B": "Breakfast", + "L": "Lunch", + "D": "Dinner", + "S": "Snack", + } + name = models.CharField(max_length=100) + main_dish = models.CharField(max_length=50) + side_dish = models.CharField(max_length=50, blank=True) + desert = models.CharField(max_length=50, blank=True) + type_of_meal = models.CharField(max_length=1, choices=TYPE_OF_MEAL.items(), blank=True) + + def __str__(self): + return self.name +``` + +Now our model is in our codebase, but we also need to add this table to our database. First, we prepare a migration file with instructions on how to do that with the following Django command. + +```shell +python manage.py makemigrations mealplan +``` + +And then, to apply those changes to the database: + +```shell +python manage.py migrate mealplan +``` + +Note: Any time you add or make changes to your models, you need to run these commands to make sure the changes apply to the database. + +## URLs + +Before we create a page that we can actually _see_, we need to configure the URLs that will lead to our (eventual) content. + +Django automatically creates a URL leading to an "Admin" section (you can read more about that in the official Django tutorial). + +```python +# app/urls.py + +from django.contrib import admin +from django.urls import path + +urlpatterns = [ + path('admin/', admin.site.urls), +] +``` + +We want to go ahead and add a pattern that will lead to any URLs defined in your `mealplan` app. Also, Django Unicorn utilizes its own pattern which needs to be added also. + +```python +# app/urls.py + +from django.contrib import admin +from django.urls import path, include # Added include + +urlpatterns = [ + path('admin/', admin.site.urls), + path("", include("mealplan.urls")), # Added for your app + path("unicorn/", include("django_unicorn.urls")), # Added for Django Unicorn +] +``` + +Django will now redirect everything that goes to your index page to `mealplan.urls`, but you'll note that there is currently not a module (a `.py` file) by that name in your `mealplan` directory. You will need to create it! + +``` +mealplan/ +┣ migrations/ +┣ admin.py +┣ apps.py +┣ models.py +┣ tests.py +┣ urls.py # New! +┣ views.py +┗ __init__.py +``` + +In that file, you can define the URLs and what "Views" will be rendered. + +```python +# mealplan/urls.py +from django.urls import path +from . import views + +urlpatterns = [ + path('', views.index, name='index'), +] + +``` + +We have not yet created a View called `index` yet, but we're getting there! + +## Views + +In Django, a _view_ is often where you might include the application logic. It also specifies what will be rendered on the browser, typically HTML contained in a _template_ file. + +You should already have a `view.py` file created for your `mealplan` app. Let's open it up and try to render a page. + +```python +# mealplan/views.py + +from django.shortcuts import render + + +def index(request) : + return render(request, "mealplan/meals.html") + +``` + +Here, we're trying to render a template called `meals.html` (it doesn't exist yet). So let's go ahead and build that template, shall we? + +## Templates + +In Django, there is a naming convention that organizes how _views_ link up to templates, and it relies on a certain directory structure. To create this first template, we need to add two directories and a file like so: + +``` +mealplan/ +┣ migrations/ +┣ templates/ # New! +┃ ┗ mealplan/ # New! +┃ ┗ meals.html # New! +┣ admin.py +┣ apps.py +┣ models.py +┣ tests.py +┣ urls.py +┣ views.py +┗ __init__.py +``` + +Django templates allow you to insert Python into your HTML. Let's build a quick template that will show us a list of all our meals (hint: we don't have any saved yet!) + +:::{code} html +:force: true + + + + +
+No meals have been prepared yet!
+ +No meals have been prepared yet!
+ {% else %} +