Добро пожаловать на то, что я надеюсь, будет очень подробным и полезным руководством по созданию веб-приложения Django с нуля к производству. Разработав десятки проектов Django PROCES, я приобрел определенные советы и трюки для повышения эффективности в каждом проекте Django, что я представлю в форме учебника. Этот учебник является пошаговым процессом того, как я иду по созданию надежных приложений Django. Наслаждаться!
Вы можете проверить развертывание здесь: Живая ссылка
Демо:
Для этого образца проекта мы пойдем за пределы простого приложения TODO или в блоге – мы создадим приложение для рецепта пищевых рецептов с полной аутентификацией пользователя, функциями Crud, а также развертывая приложение для живой продукции на Heroku.
Каталог
Первый шаг в любом новом проекте устанавливает каталог. Если вы хотите, чтобы ваш проект Django в определенном каталоге перейдите к нему, прежде чем запустить команду StartProject. Создайте новый проект Django со следующей командой:
Django-admin StartProject [ProjectName]
Это должно генерировать файловую структуру как таковую:
├─ foodanic (our sample project title) │ ├─ __init__.py │ ├─ asgi.py │ ├─ settings.py │ ├─ urls.py │ ├─ wsgi.py ├─ manage.py
Давайте быстро добавим папку с названием Шаблоны в каталог с пищевым/и управлением.
Окружающая среда
Следующим решающим шагом является виртуальная среда для содержения всех наших зависимостей в одном модуле.
Создать новую виртуальную среду:
virtualenv env
Примечание: [ENV] может быть все, что вы хотите назвать вашу виртуальную среду Активировать окружающую среду:
source env/bin/activate
Чтобы деактивировать окружающую среду:
deactivate
После того, как вы создадите и активируйте среду, тег (ENV) появится в вашем терминале рядом с именем каталога.
Настройки:
Это шаг, который вы должны запомнить для всех будущих проектов, потому что правильные начальные настройки настройки предотвратывают ошибки в будущем. В вашем settings.py Файл, в верхней части, добавить Импорт ОС Далее прокрутите вниз до Шаблоны раздел и сделайте следующие изменения в Дирижер :
import os 'DIRS': [os.path.join(BASE_DIR, 'templates')],
Это позволяет пересылать корневой шаблон проекта к главному каталогу шаблонов, для будущего ссылки на base.html файл.
Пока мы на этом, давайте установим Django в наше приложение с помощью:
pip install django
Далее мы установим промежуточное программное обеспечение, которое помогает изображениям Heroku Process Process для приложений Django под названием Whitenoise Отказ
Для установки зависимости запустить:
pip install whitenoise
Добавьте белкуаз на свой Промежуточное программное обеспечение :
# settings.py MIDDLEWARE = [ ... 'whitenoise.middleware.WhiteNoiseMiddleware', ]
Каждый раз, когда мы добавляем новую зависимость в проект, вы захотите заправить их в файл под названием требования .txt Отказ
Сделать этот бег:
pip freeze > requirements.txt
Статические и СМИ
Статические и СМИ будут служить изображениям в нашем приложении.
Ниже определенного Static_url в настройках .py, добавлять
#settings.py
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_TMP = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
os.makedirs(STATIC_TMP, exist_ok=True)
os.makedirs(STATIC_ROOT, exist_ok=True)
os.makedirs(MEDIA_ROOT, exist_ok=True)
Это устанавливает наши статические и средства массовой информации в наиболее оптимальном способе обслуживания нашего приложения.
.gitignore.
Другим важным шагом в начале проекта Django является файл .gitignore, который будет игнорировать каталоги/файлы, перечисленные там.
Создайте .gitignore с:
touch .gitignore
Добавим виртуальную среду, которую мы создали к нему, так что она не забирает дополнительное облачное пространство на Github.
# .gitignore env/
Теперь, когда у нас есть наш проект настроен так, как мы хотим, давайте начнем с создания нашего первого приложения для обработки логики. Наряду с этим, давайте также создадим приложение для пользователя, которое мы будем использовать для аутентификации пользователя в данный момент.
Создайте новое приложение с:
python manage.py startapp app python manage.py startapp users
Добавьте приложение к настройкам .py:
# settings.py
INSTALLED_APPS = [
'app',
'users',
...
]
Теперь, чтобы наши приложения были правильно маршруты в нашем веб-приложении, нам нужно включить наши другие приложения в главной Пищевой URLS.PY Отказ
# foodanic/urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('app.urls')),
path('u/', include('users.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
Программы
Внутри нового каталога приложений и пользователей давайте добавим два файла и две папки.
Files to add: Folders to add: (for each respectively) - urls.py - app/templates/app - forms.py - users/templates/users
Новое приложение и каталог пользователей будут выглядеть так:
├─ app │ ├─ migrations/ | ├─ templates | | └── app/ │ ├─ __init__.py │ ├─ admin.py │ ├─ apps.py │ ├─ forms.py │ ├─ models.py │ ├─ tests.py │ ├─ urls.py │ └── views.py │ ├─ users │ ├─ migrations/ | ├─ templates | | └── users/ │ ├─ __init__.py │ ├─ admin.py │ ├─ apps.py │ ├─ forms.py │ ├─ models.py │ ├─ tests.py │ ├─ urls.py │ └── views.py
Аутентификация пользователя
Для нашего удобства мы будем использовать основную систему аутентификации Django.
В наших настройках .py Нам нужно будет указать логин и выйти из перенаправления, например:
# foodanic/settings.py ... LOGIN_REDIRECT_URL = '/' LOGOUT_REDIRECT_URL = '/' LOGIN_URL = 'login'
В нашем недавно созданном приложении пользователей отправляйтесь на URL-адреса для включения видов аутентификации Django.
# users/urls.py
from django.urls import path
from django.conf.urls.static import static
from django.conf import settings
from django.contrib.auth import views as auth_views
from .views import *
urlpatterns = [
path('signup/', signup, name='signup'),
path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'),
path('logout/', auth_views.LogoutView.as_view(template_name='users/logout.html'), name='logout'),
path('change-password/', auth_views.PasswordChangeView.as_view(template_name='users/change-password.html'), name="change-password"),
path('password_change/done/', auth_views.PasswordChangeDoneView.as_view(template_name='users/password_reset_done.html'), name='password_change_done'),
path('password_reset/', auth_views.PasswordResetView.as_view(template_name='users/forgot-password.html', subject_template_name='users/password_reset_subject.txt', html_email_template_name='users/password_reset_email.html'), name='password_reset'),
path('password_reset/done/', auth_views.PasswordResetDoneView.as_view(template_name='users/password_reset_done.html'), name='password_reset_done'),
path('reset///', auth_views.PasswordResetConfirmView.as_view(template_name='users/password_reset_confirm.html'), name='password_reset_confirm'),
path('reset/done/', auth_views.PasswordResetCompleteView.as_view(template_name='users/password_reset_complete.html'), name='password_reset_complete'),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
Теперь это была тонна новых URL-адресов, которые мы только что добавили, давайте убедитесь, что у нас есть необходимые шаблоны. Линия ниже создаст все необходимые шаблоны, учитывая, что вы находитесь в базовом каталоге (пищевой).
touch users/templates/users/login.html && touch users/templates/users/logout.html && touch users/templates/users/change-password.html && touch users/templates/users/password_reset_done.html && touch users/templates/users/forgot-password.html && touch users/templates/users/password_reset_done.html && touch users/templates/users/password_reset_confirm.html && touch users/templates/users/password_reset_complete.html && touch users/templates/users/password_reset_email.html && touch users/templates/users/password_reset_subject.txt && touch users/templates/users/signup.html && touch users/templates/users/style.html
Теперь мы можем настроить каждый шаблон для рендера с базы и отображать соответствующую форму. Кредит на Этот кодепен для дизайна Bootstrap.
Пользователи/style.html.
Пользователи/login.html.
{% extends 'base.html' %}
{% block content %}
{% load crispy_forms_tags %}
Log in to Foodanic
{% include 'users/style.html' %}
{% endblock %}
Пользователи/logout.html.
{% extends 'base.html' %}
{% block content %}
You have successfully logged out of Foodanic. Log back in ->
{% endblock %}
Пользователи/feignup.html.
{% extends 'base.html' %}
{% block content %}
{% load crispy_forms_tags %}
Signup for Foodanic
{% include 'users/style.html' %}
{% endblock %}
Пользователи/Change-Password.html
{% extends 'base.html' %}
{% block content %}
{% load crispy_forms_tags %}
Log in to Foodanic
{% include 'users/style.html' %}
{% endblock %}
Пользователи/Password_reset_done.html.
{% extends 'base.html' %}
{% block title %}Email Sent{% endblock %}
{% block content %}
Check your inbox.
We've emailed you instructions for setting your password. You should receive the email shortly!
{% endblock %}
Пользователи/Забыли пароль .html
{% extends 'base.html' %}
{% block content %}
{% load static %}
{% load crispy_forms_tags %}
Forgot Your Password?
We get it, stuff happens. Just enter your email address below and we'll send you a link to reset your password!
{% endblock %}
Пользователи/Password_reset_subject.txt.
Foodanic Password Reset
Пользователи/Password_reset_email.html.
{% autoescape off %}
Hi, {{ user.username }}.
We received a request for a password reset. If this was you,
follow the link below to reset your password. If this wasn't you, no action is needed.
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
If clicking the link above doesn't work, please copy and paste the URL in a new browser
window instead.
Sincerely,
Foodanic
{% endautoescape %}
Пользователи/Password_reset_done.html.
{% extends 'base.html' %}
{% block title %}Email Sent{% endblock %}
{% block content %}
Check your inbox.
We've emailed you instructions for setting your password. You should receive the email shortly!
{% endblock %}
Password_reset_confirm.html.
{% extends 'base.html' %}
{% block title %}Enter new password{% endblock %}
{% load crispy_forms_tags %}
{% block content %}
{% if validlink %}
Set a new password
{% else %}
The password reset link was invalid, possibly because it has already been used. Please request a new password reset.
{% endif %}
{% endblock %}
Пользователи/Password_reset_complete.html.
{% extends 'base.html' %}
{% block title %}Password reset complete{% endblock %}
{% block content %}
Password reset complete
Your new password has been set. You can now log in.
{% endblock %}
Теперь вы можете предоставить нашу новую аутентификацию пользователя попытку, что приведет вас в туре по системе аутентификации Django. Имейте в виду, сброс пароля не будет работать, потому что мы не настроили электронный сервер с Django. Я рекомендую Это руководство Для того, чтобы помочь вам с настройкой сброса электронной почты.
Если вы хотите создать учетную запись администратора для вашего сайта, вы можете сделать это с:
python manage.py createsuperuser
Основное приложение
Вот где приходит веселая часть, мы построим операции Crud of App.
Взгляды
Просмотры контролируют логику приложения, рендурирующие функции и выполнение необходимых операций на формах, шаблонах и что-либо еще, имеющие отношение к вашему приложению.
Во-первых, мы выпишем функции, над которыми мы будем работать.
# views.py
from django.shortcuts import render
def home(request):
context = {}
return render(request, 'app/index.html', context)
def detail(request, id):
context = {}
return render(request, 'app/detail.html', context)
def create(request):
context = {}
return render(request, 'app/create.html', context)
def update(request, id):
context = {}
return render(request, 'app/update.html', context)
def delete(request, id):
context = {}
return render(request, 'app/delete.html', context)
Далее давайте добавим их в URLS.PY Файл в приложении в дополнение к URL-адресу носителя и root для обработки наших будущих изображений:
# app/urls.py
from django.urls import path
from .views import *
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path('', home, name='home'),
path('detail//', detail, name='detail'),
path('new/', create, name='create'),
path('update//', update, name='update'),
path('delete//', delete, name='delete'),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
Для того, чтобы наши URL в приложении работать должным образом, нам нужно добавить их в наш основной файл URLS.PY. Кроме того, также добавьте URL-адрес носителя и корни к основным URL-адресам.
# foodanic/urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('app.urls')),
path('u/', include('users.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
Пользователи/Views.py.
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.forms import UserCreationForm, PasswordChangeForm, AuthenticationForm
def signup(request):
context = {}
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password1')
user = request.user
if user is not None:
return redirect('login')
else:
print('user is none')
else:
form = UserCreationForm()
context['form'] = form
return render(request, 'users/signup.html', context)
# context['form'] = form
if request.method == 'GET':
form = UserCreationForm()
context['form'] = form
return render(request, 'users/signup.html', context)
Беги миграции и сервера
Теперь мы готовы начать разработку нашего веб-приложения. Давайте запустим миграции, чтобы создать начальную базу данных и запустить наше приложение.
Беги миграции с:
python manage.py migrate
Запустите сервер с:
python manage.py runserver [OPTIONAL: PORT]
Примечание. Дополнительный порт может использоваться как таковой: Python Manage.py Runserver 8000 Python Manage.py Runserver 1234
Модель
Теперь мы можем настроить нашу модель, которая будет хранить каждый рецепт.
В моделях .py Добавьте следующий код:
# app/models.py
from django.db import models
from datetime import datetime, timedelta
from markdownx.models import MarkdownxField
from django.contrib.auth.models import User
class Recipe(models.Model):
name = models.CharField(max_length=255)
description = models.TextField()
prep = models.CharField(max_length=255)
cook = models.CharField(max_length=255)
servings = models.IntegerField(default=1, null=True, blank=True)
image = models.ImageField(upload_to='media/')
ingredients = MarkdownxField()
directions = MarkdownxField()
notes = models.TextField(null=True, blank=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.name
@property
def formatted_ingredients(self):
return markdownify(self.ingredients)
@property
def formatted_directions(self):
return markdownify(self.directions)
Несколько вещей, которые следует отметить здесь: у нас есть 9 полей, которые будут проводить информацию для модели рецепта. Мы будем использовать django markdownx (GitHub Link) Для двух полей для приятного взгляда. @Property Создает тег свойства, который мы можем использовать в наших шаблонах, чтобы рендерировать поля Markdown.
Чтобы установить Django Markdown, запустите:
pip install django-markdownx
Добавьте его на settings.py:
# settings.py INSTALLED_APPS = [ 'markdownx', ... ]
Добавьте его к требованиям с:
pip freeze > requirements.txt
Добавьте его к главному URLS.PY:
# foodanic/urls.py
urlpatterns = [
path('markdownx/', include('markdownx.urls')),
]
Теперь, когда у нас есть наша модель, мы можем идти вперед и запустить миграцию. Примечание. Вы должны запускать миграции с каждым изменением, которые вы делаете в модели, чтобы база данных обновлена.
python manage.py makemigrations && python manage.py migrate
Если все прошло хорошо, вы должны увидеть вывод, аналогичный этому и совершенно новой миграции в вашем приложении миграции/ папка.
(env) ➜ foodanic git:(master) ✗ python manage.py makemigrations && python manage.py migrate
Migrations for 'app':
app/migrations/0001_initial.py
- Create model Recipe
Operations to perform:
Apply all migrations: admin, app, auth, contenttypes, sessions
Running migrations:
Applying app.0001_initial... OK
(env) ➜ foodanic git:(master) ✗
Для того, чтобы наша модель успешно отображается в администрате Django, нам нужно зарегистрировать его в файл admin.py, который так:
# app/admin.py from django.contrib import admin from .models import * admin.site.register(Recipe)
Основная форма
Чтобы быстро пройти данные в нашу базу данных, мы будем использовать модефом Django на нашей модели.
Составьте следующие изменения в файл форм:
# app/forms.py
from django import forms
from .models import *
from durationwidget.widgets import TimeDurationWidget
class RecipeForm(forms.ModelForm):
prep = forms.DurationField(widget=TimeDurationWidget(show_days=False, show_hours=True, show_minutes=True, show_seconds=False), required=False)
cook = forms.DurationField(widget=TimeDurationWidget(show_days=False, show_hours=True, show_minutes=True, show_seconds=False), required=False)
class Meta:
model = Recipe
fields = '__all__'
exclude = ('author',)
С этой формой мы сможем рендерировать все поля в модели рецепта. Кроме того, если вы хотите включить только определенные поля, вы перечислите их в массиве как таковых: поля = [«Имя», «Изображение»,] Или если вы хотите исключить определенные поля, вы бы перечисляли их как таковые: Исключить = («Имя», «Изображение»,) Отказ
Возможно, вы заметили, что мы добавили новую библиотеку, чтобы помочь нам сделать поле продолжительности для подготовки и времени готовить. Кроме того, давайте установим другой модуль, мы будем использовать позже, чтобы помочь нам с формой, Джанго хрустящие формы Отказ
Установите его с помощью PIP:
pip install django-durationwidget pip install django-crispy-forms
Добавьте его в настройки:
# settings.py
INSTALLED_APPS = [
'durationwidget',
'crispy_forms',
]
TEMPLATES = [
'APP_DIRS': True, # set to True
]
# on the bottom of settings.py
CRISPY_TEMPLATE_PACK = 'bootstrap4'
И давайте заморожем требования к сохранению зависимости:
pip freeze > requirements.txt
Грубый
Теперь мы готовы начать писать логику наших взглядов.
Давайте начнем с C в Круд Что означает (создавать, чтение, обновление, удалить)
Создавать
В наших представлениях, давайте импомнем формы, модели и визуализацию формы для получения запроса GET и POST. Запрос Get будет представлять, когда пользователь отправляется на странице, чтобы создать новый рецепт, тогда как пост будет обрабатывать логику формы после отправки.
# app/views.py
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.core.files.storage import FileSystemStorage
from datetime import datetime, timedelta
from .models import *
from .forms import *
@login_required
def create(request):
context = {}
if request.method == 'GET':
form = RecipeForm()
context['form'] = RecipeForm()
return render(request, 'app/create.html', context)
elif request.method == 'POST' and request.FILES != None:
form = RecipeForm(request.POST, request.FILES)
if form.is_valid():
new = Recipe()
user = request.user
new.author = user
new.name = form['name'].value()
new.description = form['description'].value()
new.prep = form['prep'].value()
new.cook = form['cook'].value()
new.servings = form['servings'].value()
new.ingredients = form['ingredients'].value()
new.directions = form['directions'].value()
new.notes = form['notes'].value()
theimg = request.FILES['image']
fs = FileSystemStorage()
filename = fs.save(theimg.name, theimg)
file_url = fs.url(filename)
new.image = filename
new.save()
return redirect('home')
else:
form = RecipeForm()
context['form'] = RecipeForm()
return render(request, 'app/create.html', context)
return render(request, 'app/create.html', context)
WOAH, это целый код Лотта – давайте сломаемся, поэтому мы понимаем, что это делает.
IF Заявление обрабатывает логику того, какой шаблон для рендеринга, если get и где перенаправлять пользователя после отправки, пост. запрос. Файлы В форме для нашего поля изображения. По сути, если представленная форма проходит наши параметры, мы создаем новый экземпляр модели рецепта и сохранить содержимое формы к значениям модели соответственно.
Теперь мы должны сделать шаблон для формы. Для этого нам нужно будет создать base.html Файл в наших базовых шаблонах. Я добавлю самую современную версию Bootstrap, которая является 5 – поэтому, если вы читаете этот учебник позже, обязательно обновить соответствующий CDN для Bootstrap, найден в getbootstrap.com Отказ
Пищевые/шаблоны/base.html
Foodanic
{% block content %}
{% endblock %}
Теперь у нас есть наша настройка Base.html, и мы можем оказывать другие шаблоны без ненужного контента. Я загрузил create.html Страница к прошедшему формату, но не стесняйтесь изменить дизайн, однако вы, пожалуйста.
приложение/create.html.
{% extends 'base.html' %}
{% block content %}
{% load crispy_forms_tags %}
New Recipe
Note: The Ingredients and Directions fields are Markdown Supported. Learn more about markdown here.
{{ form.media }}
{% endblock %}
В начале вы можете увидеть, что мы визуализируем информацию в тегах блока контента на основе base.html файл мы создали. Мы загружаем хрудку с тегом и установите каждое поле в виде хрустящего поля. {{form.media}} Тег оказывает контент для полей MarkDownx. В качестве альтернативы вы можете сделать всю форму как хрустящую, как это: {{form | crispy}} Отказ
Новый маршрут должен выглядеть что-то подобное:
Читать
Часть чтения CRUD связана с возможностью просмотра каждого отдельного объекта в нашей базе данных. Во-первых, мы сделаем один рецепты, тогда мы потянем весь набор нашей индексной страницы.
приложение/просмотр .py.py.
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.core.files.storage import FileSystemStorage
from datetime import datetime, timedelta
from markdownx.utils import markdownify # new
from .models import *
from .forms import *
def home(request):
recipes = Recipe.objects.all()
context = {
'recipes': recipes,
}
return render(request, 'app/index.html', context)
def detail(request, id):
recipe = get_object_or_404(Recipe, id=id)
recipe.ingredients = markdownify(recipe.ingredients)
recipe.directions = markdownify(recipe.directions)
context = {
'recipe': recipe,
}
return render(request, 'app/detail.html', context)
Шаблон ниже зачисляется пользователю Ариэлозам на кодепене.
Приложение/Detail.html.
{% extends 'base.html' %}
{% block content %}
{% load crispy_forms_tags %}
{{ recipe.name|capfirst }} Recipe {% if user.is_authenticated and request.user == recipe.author %} {% endif %}
by {{recipe.author}}
Description:
{{recipe.description}}
Servings:
{{ recipe.servings }}
Prep:
{{ recipe.prep }}
Cook:
{{ recipe.cook }}
{{ recipe.ingredients|safe }}
{{ recipe.directions|safe }}
{% endblock %}
Новый шаблон должен выглядеть так:
Теперь пришло время получить все наши рецепты для отображения на нашей домашней странице.
App/index.html.
{% extends 'base.html' %}
{% block content %}
{% load crispy_forms_tags %}
A Warm Welcome!
Browse through our collection of various recipes.
{% for recipe in recipes %}
{{recipe.name}} Recipe
{{recipe.description|truncatechars:65}}
Prep Time: {{recipe.prep}}
Cook Time: {{recipe.cook}}
{% endfor %}
{% endblock %}
С несколькими рецептами выборки вот как домашняя страница выходит на:
Обновлять
Обзор обновления будет захватывать экземпляр объекта, который мы хотим обновить и сохранить новую информацию.
приложение/просмотр .py.py.
@login_required
def update(request, id):
recipe = get_object_or_404(Recipe, id=id)
context = {
'recipe': recipe
}
if request.method == 'GET':
form = RecipeForm(instance=recipe)
context['form'] = form
return render(request, 'app/update.html', context)
elif request.method == 'POST' and request.FILES != None:
form = RecipeForm(request.POST, request.FILES, instance=recipe)
if form.is_valid():
form.save()
return redirect('detail', recipe.id)
else:
form = RecipeForm(instance=recipe)
context['form'] = form
return render(request, 'app/update.html', context)
return render(request, 'app/update.html', context)
Короткий и простой маршрут, рендеринг реплики представления CREATE, за исключением случаев, когда мы экономьте форму в целом.
app/update.html.
{% extends 'base.html' %}
{% block content %}
{% load crispy_forms_tags %}
Update Recipe
Note: The Ingredients and Directions fields are Markdown Supported. Learn more about markdown here.
{{ form.media }}
{% endblock %}
Продолжайте и дайте ему попробовать, ваша форма должна отображать вам данные объекта и правильно сохранить ее в базу данных.
Удалить
Как больно удалять объекты базы данных, иногда это то, что пользователь или мы хотим сделать.
приложение/просмотр .py.py.
@login_required
def delete(request, id):
recipe = get_object_or_404(Recipe, id=id)
if not request.user == recipe.author:
return redirect('detail', recipe.id)
else:
name = recipe.name
recipe.delete()
context = {
'name': name
}
return render(request, 'app/delete.html', context)
приложение/delete.html.
{% extends 'base.html' %}
{% block content %}
{% load crispy_forms_tags %}
{% endblock %}
Часть 3 🚗.
Сейчас мы готовы к нашему живому развертыванию к Heroku. На данный момент, пожалуйста, отправляйтесь на Github Создайте и нажимайте свой код на новый репозиторий, чтобы мы могли провести его на Heroku. Кроме того, если у вас еще нет учетной записи Heroku, отправляйтесь на Heroku Home создать один.
Кроме того, Heroku нуждается в Gunicorn, чтобы запустить, поэтому мы устанавливаем его с PIP.
pip install gunicorn pip freeze > requirements.txt
Далее нам нужен Procfile Итак, Хероку знает, чтобы запустить наше приложение с гурущим.
web: gunicorn foodanic.wsgi --log-file -
Убедитесь, что вы вошли в Heroku в своем терминале с:
heroku login
Создайте новое приложение Heroku с:
heroku create # or heroku create [app-name]
После того, как вы погрузитесь и совершаете, беги
git push heroku HEAD:master
Когда вы получаете сообщение о успехе, заявив, что ваше приложение (со ссылкой) было развернуто на Heroku, мы должны убедиться, что наше приложение принимает эту ссылку.
Питанец/Настройки
ALLOWED_HOSTS = ['[your-app].herokuapp.com']
Обязательно замените [«ваше приложение»] с соответствующим именем приложения для вашего приложения Heroku.
Затем повторить фиксацию и …
git push heroku HEAD:master
Конец
Если вы достигли конца этого учебника, вы потрясающие! Если вы столкнулись с любыми ошибками/ошибками на протяжении всего руководства, пожалуйста, не стесняйтесь публиковать их в комментариях, чтобы я мог бы быстро исправить их, прежде чем кто-то еще испытывает их. Программирование – это совместное усилие после всех 😁
Ссылки на проект:
Github repo: Ссылка Live: Ссылка на сайт
Ресурсы:
Деталь страницы кодепена: Ссылка User Auth Page CodePen: Ссылка Домашняя страница Шаблон Bootstrap: Ссылка Django Markdownx.: Ссылка Джанго хрустящие формы: Ссылка на сайт
Слияние Если есть определенные проекты/темы, которые вы хотели бы, чтобы я погрузился, бросьте их в комментарии ниже, и я сделаю все возможное, чтобы исследовать его. Спасибо за чтение 🙂
Оригинал: “https://dev.to/vladyslavnua/how-to-build-a-django-web-app-from-scratch-tutorial-5bp0”