{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Django\n",
    "\n",
    "[Course notes](https://cs50.harvard.edu/web/2019/spring/notes/7/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Project Directory Structure\n",
    "\n",
    "1. To start a Django project, enter the command below in terminal:\n",
    "\n",
    "    ```bash\n",
    "    # django-admin startproject <project-name>\n",
    "    django-admin startproject project_name\n",
    "    ```\n",
    "\n",
    "2. To create an app, cd to the project root (`project_name/` in this case) and run:\n",
    "\n",
    "    ```bash\n",
    "    # python manage.py startapp <app-name>\n",
    "    python manage.py startapp app1\n",
    "    ```\n",
    "\n",
    "\n",
    "This creates the directory stucture below:\n",
    "\n",
    "```yaml\n",
    "project_name/\n",
    "├── project_name/    # website App: project-level configurations\n",
    "│   ├── __init__.py\n",
    "│   ├── settings.py  # Link Apps: INSTALLED_APPS\n",
    "│   ├── urls.py      # Link apps' routes to main site \n",
    "│   └── wsgi.py\n",
    "│ \n",
    "├── app1/\n",
    "│   ├── migrations/\n",
    "│   ├── templates/\n",
    "│   │   └── app1/\n",
    "│   │       ├── base.html\n",
    "│   │       └── index.html\n",
    "│   ├── static/\n",
    "│   │       └── style.css\n",
    "│   ├── __init__.py\n",
    "│   ├── admin.py     # Customize administrator panel\n",
    "│   ├── apps.py\n",
    "│   ├── tests.py\n",
    "│   ├── models.py    # app database definition\n",
    "│   ├── urls.py      # app route\n",
    "│   └── views.py     # app functions\n",
    "│\n",
    "├── manage.py\n",
    "└── db.sqlite3\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Common Commands\n",
    "\n",
    "- Start new Django project\n",
    "    ```bash\n",
    "    django-admin startproject <project-name>\n",
    "    ```\n",
    "    \n",
    "- Add new app\n",
    "    ```bash\n",
    "    python manage.py startapp <app-name>\n",
    "    ```\n",
    "\n",
    "- Start server\n",
    "    ```bash\n",
    "    python manage.py runserver\n",
    "    ```\n",
    "\n",
    "- Update database (after modifying `<app-name>/models.py`\n",
    "    ```bash\n",
    "    python manage.py makemigrations\n",
    "    python manage.py migrate\n",
    "    ```\n",
    "\n",
    "- Django shell\n",
    "    ```bash\n",
    "    python manage.py shell\n",
    "    python manage.py shell < script.py\n",
    "    ```\n",
    "\n",
    "- Create super user account\n",
    "    ```bash\n",
    "    python manage.py createsuperuser\n",
    "    ```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## `settings.py`\n",
    "\n",
    "Every time a new app is created, remember to attach this new app to the project. To do this, find `INSTALLED_APPS` in `project_name/settings.py` and add the app to the list:\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## `urls.py`\n",
    "\n",
    "Every app has one `urls.py` and `project_name/` has one `urls.py`. `project_name/urls.py` defines the url relations of every app to the site. `<app-name>/urls.py` defines the relations between individual functions in `<app-name>/views.py` and url paths **within** an app.\n",
    "\n",
    "\n",
    "For example, `project_name/urls.py` might look like the code below, where `flights`, `users` and `admin` (default Django app) are apps in the project:\n",
    "\n",
    "```python\n",
    "from django.contrib import admin\n",
    "from django.urls import path, include\n",
    "\n",
    "urlpatterns = [\n",
    "    path('flights/', include('flights.urls')),\n",
    "    path('users/', include('users.urls')),\n",
    "    path('admin/', admin.site.urls),\n",
    "]\n",
    "```\n",
    "\n",
    "\n",
    "`flights/urls.py` may look like the code below:\n",
    "\n",
    "```python\n",
    "from django.urls import path\n",
    "from . import views\n",
    "\n",
    "urlpatterns = [\n",
    "    path('', views.index, name='index'),\n",
    "    path('<int:flight_id>', views.flight, name='flight'),\n",
    "    path('<int:flight_id>/book', views.book, name='book')\n",
    "]\n",
    "```\n",
    "\n",
    "The `path` functions essentially links the functions in `views.py` and url paths together in an app.\n",
    "\n",
    "\n",
    "As an example, (after running the server locally) if you visit `http://127.0.0.1:8000/flights/1/book`, you will be on a page handled by the function `book()` defined in `flights/views.py`. This relationship is defined in `path('<int:flight_id>/book', views.book, name='book')`. The path right after the base url (`http://127.0.0.1:8000/`) is `flights/` because it was defined in `path('flights/', include('flights.urls')),` in `project_name/urls.py`."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}