カンフーシート
目次
Django Project Initiation
Models
Paths
Views
Templates
Authentication
Helpful Commands & Syntax
ワークフロー
私はdjangoプロジェクトを作成するたびに、進行中のワークフローの順序に従う傾向があります.心に留めておいてください、これはただ一つの可能なワークフローです、そして、あなたはあなたのためによりよく働く1つを見つけるかもしれません!
⚠️ Don't Skip the Docs! I mostly wrote this guide to help myself, and while I am more than happy to share it with anyone who finds it useful, I can't recommend enough getting comfortable with reading the official documentation!
📝 Note: The structure of this cheat sheet more or less follows the order of the workflow above. There is also a section of helpful tips and other general syntax bits at the bottom. Feel free to skip around!
設定する
を返します。
# create the project directory
~$ mkdir <<project_name>>
# access that directory
~$ cd <<project_name>>
# initialize a git repo within that directory
~$ git init
既存のレポから始めるならば
# fork the project (if necessary)
# clone your forked copy to your computer
~$ git clone <<repo_url>>
# access that directory
~$ cd <<project_name>>
プロジェクト開始:
仮想環境を作成します
# create your virtual environment (make sure you are
# still within that directory!)
~$ python -m venv .venv
# activate that virtual environment
~$ source .venv/bin/activate # Mac OS
C:> ./.venv/Scripts/Activate.ps1 # Windows
# to deactivate your virtual environment
~$ deactivate
パッケージをインストールします
# install Django
~$ python -m pip install Django
# upgrade Django (if necessary)
~$ pip install -U Django
# upgrade pip (if necessary)
~$ python -m pip install --upgrade pip # Mac OS
C:> py -m pip install --upgrade pip # Windows
依存関係のインストール
# to create a requirements file that contains
# your project dependencies
~$ pip freeze > requirements.txt
# to install your project requirements
# (if a file already exists)
~$ pip install -r requirements.txt
Djangoプロジェクトを生成する
📝 Note: Don't forget the "." after your project name!
# create your django project
~$ django-admin startproject <<name>> .
# create your django app(s)
~$ python manage.py startapp <<name>>
# to update your database for the migrations that
# come with a default django installation
~$ python manage.py migrate
# create a superuser to access the admin
~$ python manage.py createsuperuser
# add your app(s) to the django project's settings.py
INSTALLED_APPS = [
"app_name.apps.AppNameConfig",
. . .
]
開発サーバ
# to start your development server
~$ python manage.py runserver => ex. http://127.0.0.1:8000
# to add localhost for use in development in
# project's settings.py
ALLOWED_HOSTS = [
"localhost",
. . .
]
モデル
モデル作成
これらのモデルは、移動コマンドでデータベーステーブルとして作成する必要があります.注意してください“id”フィールドは自動的にデフォルトでモデルのdjangoによって作成されます.
# app_name/models.py
from django.db import models
class Customer(models.Model)
name = models.Charfield('Customer', max_length=120)
age = models.IntegerField()
note = models.TextField(blank=True, null = True)
email = models.EmailField(max_length=255, blank=True, null=True)
credit = models.FloatField(blank=True)
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
# Create a Select Field (return value, display value)
# If this is given, the default form widget will be a
# select box instead of the standard text field and will
# limit choices to the choices given.
TYPE_CHOICES = (
('Customer', 'Customer'),
('Supplier', 'Supplier'),
('Student', 'Student'),
)
type = models.CharField(choices=TYPE_CHOICES)
# model string representation
def __str__(self):
return self.name
モデル間の関係
# One-to-Many:
supplier = models.ForeignKey(Supplier, blank=True, null=True, on_delete=models.CASCADE)
# where "Supplier" is the name of the model that the
# field is referencing
# on_delete can be set to models.CASCADE, models.ST_DEFAULT or models.SET_NULL
# Many-to-Many:
tags = models.ManyToManyField(Tag, blank=True)
# One to One
User = models.OneToOneField(User, on_delete=models.CASCADE)
いくつかのモデルの例は、いくつかのいくつかを表示し、いくつかの多くの関係を表示します.from django.db import models
from django.conf import settings
USER_MODEL = settings.AUTH_USER_MODEL
# Create your models here.
class Recipe(models.Model):
name = models.CharField(max_length=125)
author = models.ForeignKey(
USER_MODEL,
related_name="recipes",
on_delete=models.CASCADE,
null=True,
)
description = models.TextField()
image = models.URLField(null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
servings = models.PositiveSmallIntegerField(null=True)
def __str__(self):
return f"{self.name} by {self.author}"
class Step(models.Model):
recipe = models.ForeignKey(
"Recipe",
related_name="steps",
on_delete=models.CASCADE,
)
order = models.PositiveSmallIntegerField()
directions = models.CharField(max_length=300)
food_items = models.ManyToManyField("FoodItem", blank=True)
def __str__(self):
return f"{self.order} {self.directions}"
管理パネルのモデル
Localhostの管理パネルでモデルオブジェクトを表示するには:AddCount Name/Adminでアプリケーションの管理ファイルにモデルを登録します.Py管理パネルで使用するフィールドを指定することもできます.
from django.contrib import admin
from app_name.models import ModelName
# Register your models here
# Custom model Admin (admin.py):
class BlogAdmin(admin.ModelAdmin)
fields = ("title", "description") # Fields to use for add/edit/show page
list_display = ("title", "description") # fields to display in search page
list_display_links = ("title") # fields that will be a link in search page
ordering("date_created",) # Ordering allowed in the search page
search_fields("title", "description") # Search fields allowed in the search page
# Register app
admin.site.register(Blog, BlogAdmin)
パス
ルーティング
それぞれのアプリケーションのURLに格納されたパスを接続する必要があります.PyファイルをプロジェクトのURLに.Py - name/URLにおけるPy.Py
from django.contrib import admin
from django.urls import path, include, reverse_lazy
from django.views.generic.base import RedirectView
urlpatterns = [
path('admin/', admin.site.urls), # Django adds this automatically
path("", include('app_name.urls')) # include your app urls with include()
path("recipes/", include('recipes.urls')),
path("", RedirectView.as_view(url=reverse_lazy("recipes_list")), name="home"), # write a redirect view for your home page like this
]
アプリケーションパス
from django.urls import path
from recipes.views import (
RecipeCreateView,
RecipeDeleteView,
RecipeUpdateView,
log_rating,
create_shopping_item,
delete_all_shopping_items,
ShoppingItemListView,
RecipeDetailView,
RecipeListView,
)
urlpatterns = [
path("", RecipeListView.as_view(), name="recipes_list"),
path("<int:pk>/", RecipeDetailView.as_view(), name="recipe_detail"),
path("<int:pk>/delete/", RecipeDeleteView.as_view(), name="recipe_delete"),
path("new/", RecipeCreateView.as_view(), name="recipe_new"),
path("<int:pk>/edit/", RecipeUpdateView.as_view(), name="recipe_edit"),
path("<int:recipe_id>/ratings/", log_rating, name="recipe_rating"),
path("shopping_items/create", create_shopping_item, name="shopping_item_create"),
path("shopping_items/delete", delete_all_shopping_items, name="delete_all_shopping_items"),
path("shopping_items/", ShoppingItemListView.as_view(), name="shopping_items_list"),
]
フォーム
from django import forms
from recipes.models import Rating
class RatingForm(forms.ModelForm):
class Meta:
model = Rating
fields = ["value"]
# Render form in templates
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<div class="control">
<button class="button">Create</button>
</div>
</form>
見解
クラスベースのビュー
from django.shortcuts import redirect
from django.urls import reverse_lazy
from django.views.generic.detail import DetailView
from django.views.generic.edit import CreateView, DeleteView, UpdateView
from django.views.generic.list import ListView
from django.contrib.auth.mixins import LoginRequiredMixin
from recipes.forms import RatingForm
from recipes.models import Recipe, Ingredient, ShoppingItem
class RecipeListView(ListView):
model = Recipe
template_name = "recipes/list.html"
paginate_by = 2
class RecipeDetailView(DetailView):
model = Recipe
template_name = "recipes/detail.html"
# Optional: change context data dictionary
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["rating_form"] = RatingForm()
foods = []
for item in self.request.user.shopping_items.all():
foods.append(item.food_item)
context["servings"] = self.request.GET.get("servings")
context["food_in_shopping_list"] = foods
return context
class RecipeCreateView(LoginRequiredMixin, CreateView):
model = Recipe
template_name = "recipes/new.html"
fields = ["name", "servings", "description", "image"]
success_url = reverse_lazy("recipes_list")
# Optional: overwrite form data (before save)
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
class RecipeUpdateView(LoginRequiredMixin, UpdateView):
model = Recipe
template_name = "recipes/edit.html"
fields = ["name", "servings", "description", "image"]
success_url = reverse_lazy("recipes_list")
class RecipeDeleteView(LoginRequiredMixin, DeleteView):
model = Recipe
template_name = "recipes/delete.html"
success_url = reverse_lazy("recipes_list")
関数ベースビュー
from django.shortcuts import redirect
from django.urls import reverse_lazy
from django.db import IntegrityError
# Create your views here.
def log_rating(request, recipe_id):
if request.method == "POST":
form = RatingForm(request.POST)
if form.is_valid():
rating = form.save(commit=False)
try:
rating.recipe = Recipe.objects.get(pk=recipe_id)
except Recipe.DoesNotExist:
return redirect("recipes_list")
rating.save()
return redirect("recipe_detail", pk=recipe_id)
def create_shopping_item(request):
ingredient_id = request.POST.get("ingredient_id")
ingredient = Ingredient.objects.get(id=ingredient_id)
user = request.user
try:
ShoppingItem.objects.create(
food_item=ingredient.food,
user=user,
)
except IntegrityError:
pass
return redirect("recipe_detail", pk=ingredient.recipe.id)
テンプレート
あなたのHTMLテンプレートはAppRoundフォルダ/テンプレート/appChangesの名前に格納する必要があります.
ベーステンプレート
基地.HTMLはあなたのルートテンプレートディレクトリに保存する必要があります
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %} {% endblock %}Scrumptious Recipes</title>
<link rel="stylesheet" href="{% static 'css/app.css' %}">
</head>
<body>
<header>
<nav>
<ul>
<li>
<a href="{% url 'home' %}">Scrumptious</a>
</li>
{% if user.is_staff %}
<li>
<a href="{% url 'admin:index' %}">Admin</a>
</li>
{% endif %}
<li>
<a href="{% url 'recipe_new' %}">Write a recipe</a>
</li>
<li>
<a href="{% url 'tags_list' %}">Tags</a>
</li>
{% if not user.is_authenticated %}
<li>
<a href="{% url 'login' %}">Login</a>
</li>
{% endif %}
{% if user.is_authenticated %}
<li>
<a href="{% url 'meal_plans_list' %}">Meal Plans</a>
</li>
<li>
<a href="{% url 'shopping_items_list' %}">Shop List ({{ user.shopping_items.all|length }})</a>
</li>
<li>
<a href="{% url 'logout' %}">Logout</a>
</li>
{% endif %}
</ul>
</nav>
{% block pagination %}
{% endblock pagination %}
{% block create %}
{% endblock create %}
</header>
{% block content %}
{% endblock content %}
</body>
</html>
ページテンプレート
{% extends 'base.html' %}
{% block pagination %}
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
<a href="?page=1">« first</a>
<a href="?page={{ page_obj.previous_page_number }}">previous</a>
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">next</a>
<a href="?page={{ page_obj.paginator.num_pages }}">last »</a>
{% endif %}
</span>
</div>
{% endblock pagination %}
DeleteViewテンプレート
{% extends 'base.html' %}
{% block title %}
Delete {{ recipe.name }} |
{% endblock %}
{% block content %}
<main>
<form method="post">
{% csrf_token %}
<p>Are you sure you want to delete "{{ recipe }}"?</p>
{{ form.as_p }}
<div class="control">
<button class="button">Delete</button>
</div>
</form>
</main>
{% endblock content %}
DetailViewテンプレート
{% extends 'base.html' %}
{% load markdownify %}
{% load resizer %}
{% block title %}
{{ recipe.name }} |
{% endblock %}
{% block content %}
<main class="recipe-detail">
<div>
<a href="{% url 'recipe_edit' recipe.id %}">Edit</a>
<a href="{% url 'recipe_delete' recipe.id %}">Delete</a>
</div>
{% if recipe.image %}
<img src="{{ recipe.image }}" class="pull-right">
{% endif %}
<h1>{{ recipe.name }}</h1>
<h2>by: {{ recipe.author | default_if_none:"Unknown" }}</h2>
<p>
Created on {{ recipe.created }} |
Updated on {{ recipe.updated }}
</p>
{% if recipe.servings %}
<p>
Serves {{ servings|default_if_none:recipe.servings }}
</p>
<form method="GET">
<input required type="number" name="servings">
<button>Resize</button>
</form>
{% endif %}
<form method="post" action="{% url 'recipe_rating' recipe.id %}">
{% csrf_token %}
<div class="rating-form-grid">
{{ rating_form.as_p }}
<button class="button">Rate</button>
</div>
</form>
<p>Tags: {% for tag in recipe.tags.all %}{{ tag.name }} {% endfor %}</p>
<p>{{ recipe.description | markdownify }}</p>
<h2>Ingredients</h2>
<table>
<thead>
<tr>
<th colspan="2">Amount</th>
<th>Food item</th>
</tr>
</thead>
<tbody>
{% for ingredient in recipe.ingredients.all %}
<tr>
<td>{{ ingredient|resize_to:servings }}</td>
<td>{{ ingredient.measure.name }}</td>
<td>{{ ingredient.food.name }}</td>
<td>
{% if ingredient.food not in food_in_shopping_list %}
<form method="POST" action="{% url 'shopping_item_create' %}">
{% csrf_token %}
<input type="hidden" name="ingredient_id" value="{{ ingredient.id }}">
<button>+ shopping list</button>
</form>
{% else %}
in your list
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<h2>Steps</h2>
<ol>
{% for step in recipe.steps.all %}
<li>{{ step.directions }}</li>
{% endfor %}
</ol>
</main>
{% endblock content %}
UpdateViewテンプレート
{% extends 'base.html' %}
{% block title %}
Edit {{ recipe.name }} |
{% endblock %}
{% block content %}
<main class="recipe-form">
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<div class="control">
<button class="button">Update</button>
</div>
</form>
</main>
{% endblock content %}
ListViewテンプレート
{% extends 'paginate.html' %}
{% block title %}
Recipes |
{% endblock %}
{% block content %}
<main class="recipe-grid">
{% for recipe in recipe_list %}
<div class="recipe-card">
<h2 class="recipe-card-title">
<a href="{% url 'recipe_detail' recipe.pk %}">{{ recipe.name }}</a>
</h2>
<p class="recipe-card-date">{{ recipe.updated }}</p>
</div>
{% endfor %}
</main>
{% endblock content %}
CreateViewテンプレート
{% extends 'base.html' %}
{% block title %}
New Recipe |
{% endblock %}
{% block content %}
<main class="recipe-form">
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<div class="control">
<button class="button">Create</button>
</div>
</form>
</main>
{% endblock content %}
認証
LoginView
これはアカウント/URLで行われます.LoginViewはすでにあなたのためにDjangoで作られているPYは、.
# import the pre-made LoginView from Django
# in your accounts/urls.py file
from django.contrib.auth.views import LoginView
LoginViewテンプレート
# By default the LoginView will try to open a
# template name 'registration/login.html' and
# send a login form with it.
# create a template at that location
{% extends 'base.html' %}
{% block title %}
Login |
{% endblock title %}
{% block content %}
<main>
<div class="narrow-form">
<h1>Login</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button>Login</button>
</form>
</div>
</main>
{% endblock content %}
ログ出力
# this one is also pre-created by Django
# import it into accounts/urls.py
from django.contrib.auth.views import LogoutView
LogoutViewテンプレート
{% extends 'base.html' %}
{% block title %}
Logged Out |
{% endblock title %}
{% block content %}
<div class="narrow-form">
<h1>Logged out</h1>
<p>You're all logged out!</p>
</div>
{% endblock content %}
サインアップ
このビューは、デフォルトでLoginViewとLogoutViewのように作成されません.ユーザー定義のフォームはデフォルトでdjangoによって作成されます.しかし、SignUpViewはそうではありません.したがって、サインアップフォームを示して、その服従を扱います.
from django.contrib.auth import login
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import render, redirect
def signup(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
username = request.POST.get("username")
password = request.POST.get("password1")
user = User.objects.create_user(
username=username,
password=password,
)
user.save()
login(request, user)
return redirect("home")
else:
form = UserCreationForm()
context = {
"form": form,
}
return render(request, "registration/signup.html", context)
サインアップテンプレート
{% extends 'base.html' %}
{% block title %}
Sign up |
{% endblock title %}
{% block content %}
<main>
<h1>Sign Up</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Sign Up</button>
</form>
</main>
{% endblock content %}
アカウントパス
あなたが作成したすべてのビューに到達するためのパスを追加することを忘れないでください!ここでは、アカウントのアプリのURLの例です.Pyファイルは(アカウント/URL ls . py )のようになります.
from django.urls import path
from django.contrib.auth.views import LoginView, LogoutView
from accounts.views import signup
urlpatterns = [
path("login/", LoginView.as_view(), name="login"),
path("logout/", LogoutView.as_view(), name="logout"),
path("signup/", signup, name="signup"),
]
役に立つコマンド/構文
ジャンゴ移動
DJango移動は、モデルと手をつなぎます:新しいモデルを書くか、既存のものを更新するときは、データベースに必要なテーブルを作成するために移行を生成する必要があります.注意:実際の移行ファイルは、ディレクトリ内のappname name/migrationsの下に作成されます.
# to make migrations
~$ python manage.py makemigrations
# to run migrations
~$ python manage.py migrate
プロジェクト構成
# App templates folder
create folder app_folder/templates/app_name
# Project templates folder:
create folder project_name/templates
# settings.py template config
Project templates settings.py:
TEMPLATES = [
{ …
'DIRS': [BASE_DIR / 'templates', ],
… }
# Create Static folder:
project_name\static\
# Static folder (settings.py):
STATIC_URL = '/static/'
STATICFILES_DIRS = [ BASE_DIR / 'static' ]
STATIC_ROOT = 'static_root'
Reference
この問題について(カンフーシート), 我々は、より多くの情報をここで見つけました https://dev.to/eklaassen/django-cheat-sheet-4fjdテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol