カンフーシート


目次

  • Workflow
  • Set Up

  • Django Project Initiation
  • Virtual Environment
  • Django Installation
  • Dependencies
  • Generate Project
  • Development Server

  • Models
  • Creating Models
  • Model Relationships
  • Admin

  • Paths
  • Routing
  • App Paths
  • Forms

  • Views
  • Class-based views
  • Function-based views

  • Templates
  • base.html
  • paginate.html
  • delete.html
  • detail.html
  • edit.html
  • list.html
  • new.html

  • Authentication
  • LoginView
  • LoginView Template
  • LogoutView
  • LogoutView Template
  • SignupView
  • SignupView Template
  • Accounts paths

  • Helpful Commands & Syntax
  • migrations
  • project config
  • ワークフロー


    私はdjangoプロジェクトを作成するたびに、進行中のワークフローの順序に従う傾向があります.心に留めておいてください、これはただ一つの可能なワークフローです、そして、あなたはあなたのためによりよく働く1つを見つけるかもしれません!
  • プロジェクトディレクトリの準備
  • 仮想環境の作成
  • インストール/アップグレード
  • 依存関係のインストール
  • プロジェクトを作成する
  • Djangoアプリの作成
  • クリエイトスーパーユーザ
  • プロジェクトの設定にアプリケーションを追加します.パイ
  • 初期移行を実行する
  • 開発サーバを起動する
  • モデル作成
  • あなたのモデルの書き込み/実行テスト
  • あなたの移動を行い、それらを実行する
  • あなたのフォームを作成します
  • あなたのビューを作成する
  • 更新あなたのパスをあなたのビュー
  • ビューのテンプレートを作成する
  • お客様のビューに書き込み/実行テスト
  • ⚠️ 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">&laquo; 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 &raquo;</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'