├── LICENSE └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Lucien Rae 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # :scroll: Django Cheat Sheet 2 | A cheat-sheet for creating web apps with the Django framework using the Python language. Most of the summaries and examples are based on [the official documentation](https://docs.djangoproject.com/en/2.0/) for Django v2.0. 3 | 4 | ## Sections 5 | - :snake: [Initializing pipenv](#snake-initializing-pipenv-optional) (optional) 6 | - :blue_book: [Creating a project](#blue_book-creating-a-project) 7 | - :page_with_curl: [Creating an app](#page_with_curl-creating-an-app) 8 | - :tv: [Creating a view](#tv-creating-a-view) 9 | - :art: [Creating a template](#art-creating-a-template) 10 | - :ticket: [Creating a model](#ticket-creating-a-model) 11 | - :postbox: [Creating model objects and queries](#postbox-creating-model-objects-and-queries) 12 | - :man: [Using the Admin page](#man-using-the-admin-page) 13 | 14 | 15 | ## :snake: Initializing pipenv (optional) 16 | - Make main folder with `$ mkdir ` and navigate to it with `$ cd ` 17 | - Initialize pipenv with `$ pipenv install` 18 | - Enter pipenv shell with `$ pipenv shell` 19 | - Install django with `$ pipenv install django` 20 | - Install other package dependencies with `$ pipenv install ` 21 | 22 | ## :blue_book: Creating a project 23 | - Navigate to main folder with `$ cd ` 24 | - Create project with `$ django-admin startproject ` 25 | 26 | The project directory should look like this: 27 | ``` 28 | project/ 29 | manage.py 30 | project/ 31 | __init__.py 32 | settings.py 33 | urls.py 34 | wsgi.py 35 | ``` 36 | - Run the development server with `$ python manage.py runserver` within the project directory 37 | - If you want your `SECRET_KEY` to be more secure, you can set it to reference an environment variable 38 | - In the `settings.py` file within the project directory change the `SECRET_KEY` line to the following: 39 | ```python 40 | SECRET_KEY = os.environ.get('SECRET_KEY') 41 | ``` 42 | - To quickly generate a random hex for your secret key: 43 | ```python 44 | >>> import secrets 45 | >>> secrets.token_hex() 46 | ``` 47 | - You can set this environment variable in your shell with `export SECRET_KEY=` 48 | 49 | ## :page_with_curl: Creating an app 50 | - Navigate to the outer project folder `$ cd ` 51 | - Create app with `$ python manage.py startapp ` 52 | - Inside the `app` folder, create a file called `urls.py` 53 | 54 | The project directory should now look like this: 55 | ``` 56 | project/ 57 | manage.py 58 | db.sqlite3 59 | project/ 60 | __init__.py 61 | settings.py 62 | urls.py 63 | wsgi.py 64 | app/ 65 | migrations/ 66 | __init__.py 67 | __init__.py 68 | admin.py 69 | apps.py 70 | models.py 71 | tests.py 72 | urls.py 73 | views.py 74 | ``` 75 | - To include this app in your project, add your app to the project's `settings.py` file by adding its name to the `INSTALLED_APPS` list: 76 | ```python 77 | INSTALLED_APPS = [ 78 | 'app', 79 | # ... 80 | ] 81 | ``` 82 | - To migrate changes over: 83 | ```bash 84 | $ python manage.py migrate 85 | ``` 86 | 87 | ## :tv: Creating a view 88 | - Within the app directory, open `views.py` and add the following: 89 | ```python 90 | from django.http import HttpResponse 91 | 92 | def index(request): 93 | return HttpResponse("Hello, World!") 94 | ``` 95 | - Still within the app directory, open (or create) `urls.py` 96 | ```python 97 | from django.urls import path 98 | from . import views 99 | 100 | urlpatterns = [ 101 | path('', views.index, name='index'), 102 | ] 103 | ``` 104 | - Now within the project directory, edit `urls.py` to include the following 105 | ```python 106 | from django.contrib import admin 107 | from django.urls import include, path 108 | 109 | urlpatterns = [ 110 | path('app/', include('app.urls')), 111 | path('admin/', admin.site.urls), 112 | ] 113 | ``` 114 | - To create a url pattern to the index of the site, use the following urlpattern: 115 | ```python 116 | urlpatterns = [ 117 | path("", include('app.urls')), 118 | ] 119 | ``` 120 | - Remember: there are multiple files named `urls.py` 121 | - The `urls.py` file within app directories are organized by the `urls.py` found in the project folder. 122 | 123 | ## :art: Creating a template 124 | - Within the app directory, HTML, CSS, and JavaScript files are located within the following locations: 125 | ``` 126 | app/ 127 | templates/ 128 | index.html 129 | static/ 130 | style.css 131 | script.js 132 | ``` 133 | - To add a template to views, open `views.py` within the app directory and include the following: 134 | ```python 135 | from django.shortcuts import render 136 | 137 | def index(request): 138 | return render(request,'index.html') 139 | ``` 140 | - To include context to the template: 141 | ```python 142 | def index(request): 143 | context = {"context_variable": context_variable} 144 | return render(request,'index.html', context) 145 | ``` 146 | - Within the HTML file, you can reference static files by adding the following: 147 | ```html 148 | {% load static %} 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | ``` 160 | - To make sure to include the following in your `settings.py`: 161 | ```python 162 | STATIC_URL = '/static/' 163 | STATICFILES_DIRS = [ 164 | os.path.join(BASE_DIR, "static") 165 | ] 166 | ``` 167 | - To add an `extends`: 168 | ```html 169 | {% extends 'base.html'%} 170 | 171 | {% block content %} 172 | 173 | Hello, World! 174 | 175 | {% endblock %} 176 | ``` 177 | - And then in `base.html` add: 178 | ```html 179 | 180 | {% block content %}{% endblock %} 181 | 182 | ``` 183 | 184 | ## :ticket: Creating a model 185 | - Within the app's `models.py` file, an example of a simple model can be added with the following: 186 | ```python 187 | from django.db import models 188 | 189 | class Person(models.Model): 190 | first_name = models.CharField(max_length=30) 191 | last_name = models.CharField(max_length=30) 192 | ``` 193 | *Note that you don't need to create a primary key, Django automatically adds an IntegerField.* 194 | 195 | - To perform changes in your models, use the following commands in your shell: 196 | ``` 197 | $ python manage.py makemigrations 198 | $ python manage.py migrate 199 | ``` 200 | *Note: including is optional.* 201 | - A one-to-many relationship can be made with a `ForeignKey`: 202 | ```python 203 | class Musician(models.Model): 204 | first_name = models.CharField(max_length=50) 205 | last_name = models.CharField(max_length=50) 206 | instrument = models.CharField(max_length=100) 207 | 208 | class Album(models.Model): 209 | artist = models.ForeignKey(Musician, on_delete=models.CASCADE) 210 | name = models.CharField(max_length=100) 211 | release_date = models.DateField() 212 | num_stars = models.IntegerField() 213 | ``` 214 | - In this example, to query for the set of albums of a musician: 215 | ```python 216 | >>> m = Musician.objects.get(pk=1) 217 | >>> a = m.album_set.get() 218 | ``` 219 | 220 | - A many-to-many relationship can be made with a `ManyToManyField`: 221 | ```python 222 | class Topping(models.Model): 223 | # ... 224 | pass 225 | 226 | class Pizza(models.Model): 227 | # ... 228 | toppings = models.ManyToManyField(Topping) 229 | ``` 230 | *Note that the `ManyToManyField` is **only defined in one model**. It doesn't matter which model has the field, but if in doubt, it should be in the model that will be interacted with in a form.* 231 | 232 | - Although Django provides a `OneToOneField` relation, a one-to-one relationship can also be defined by adding the kwarg of `unique = True` to a model's `ForeignKey`: 233 | ```python 234 | ForeignKey(SomeModel, unique=True) 235 | ``` 236 | 237 | - For more detail, the [official documentation for database models]( https://docs.djangoproject.com/en/2.0/topics/db/models/) provides a lot of useful information and examples. 238 | 239 | ## :postbox: Creating model objects and queries 240 | - Example `models.py` file: 241 | ```python 242 | from django.db import models 243 | 244 | class Blog(models.Model): 245 | name = models.CharField(max_length=100) 246 | tagline = models.TextField() 247 | 248 | def __str__(self): 249 | return self.name 250 | 251 | class Author(models.Model): 252 | name = models.CharField(max_length=200) 253 | email = models.EmailField() 254 | 255 | def __str__(self): 256 | return self.name 257 | 258 | class Entry(models.Model): 259 | blog = models.ForeignKey(Blog, on_delete=models.CASCADE) 260 | headline = models.CharField(max_length=255) 261 | body_text = models.TextField() 262 | pub_date = models.DateField() 263 | mod_date = models.DateField() 264 | authors = models.ManyToManyField(Author) 265 | n_comments = models.IntegerField() 266 | n_pingbacks = models.IntegerField() 267 | rating = models.IntegerField() 268 | 269 | def __str__(self): 270 | return self.headline 271 | ``` 272 | - To create an object within the shell: 273 | ``` 274 | $ python manage.py shell 275 | ``` 276 | ```python 277 | >>> from blog.models import Blog 278 | >>> b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.') 279 | >>> b.save() 280 | ``` 281 | - To save a change in an object: 282 | ```python 283 | >>> b.name = 'The Best Beatles Blog' 284 | >>> b.save() 285 | ``` 286 | - To retrieve objects: 287 | ```python 288 | >>> all_entries = Entry.objects.all() 289 | >>> indexed_entry = Entry.objects.get(pk=1) 290 | >>> find_entry = Entry.objects.filter(name='Beatles Blog') 291 | ``` 292 | 293 | ## :man: Using the Admin page 294 | - To create a `superuser`: 295 | ```bash 296 | $ python manage.py createsuperuser 297 | ``` 298 | - To add a model to the Admin page include the following in `admin.py`: 299 | ```python 300 | from django.contrib import admin 301 | from .models import Author, Book 302 | 303 | admin.site.register(Author) 304 | admin.site.register(Book) 305 | ``` 306 | --------------------------------------------------------------------------------