Что нового
  • Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

Создаем Свое Первое Веб-приложение При Помощи Django

Sascha

Заместитель Администратора
Команда форума
Администратор
Регистрация
9 Май 2015
Сообщения
1,071
Баллы
155
Возраст
51
Django — это Open Source фреймворк для создания веб-приложений различной сложности. Одним из основных преимуществ Django является то, что вам нужно позаботиться только о логике вашего будущего приложения, остальное сделает Django.

Мы создадим веб-приложение, у которого будет панель администратора и возможность загружать загадки, а у пользователей, соответственно, возможность отвечать на них. Во время разработки будут использоваться Python 3.4.3 и Django 1.9.1.

Устанавливаем Django


Делается это очень просто, в командной строке нужно написать: pip install Django==1.9.1.

Создаем проект


Если вы правильно установили Django, то после запуска django-admin --version вы увидите текущую версию фреймворка. Теперь создадим проект. Это можно сделать следующим образом: django-admin startproject django_example.

Как только создание проекта будет завершено, взглянем на директорию нашего проекта:

  • django_example/__init__.py — пустой файл, который говорит Python, что данная директория должна восприниматься в качестве пакета.
  • django_example/settings.py содержит конфигурацию нашего проекта.
  • django_example/urls.py — здесь объявляются URL.
  • django_example/wsgi.py — с помощью него приложение может работать с веб-сервером по протоколу WSGI.
  • manage.py позволяет взаимодействовать с проектом.

Теперь пришло время запустить наше приложение. Для этого в командной строке нужно написать python manage.py runserver. После этого в адресной строке браузера нужно написать: http://127.0.0.1:8000/. Если вы увидели «You have unapplied migrations; your app may not work properly until they are applied.», то не волнуйтесь, мы вернемся к этому чуть позже.

Создаем приложение


Определим различие между проектом и приложением. Приложение — это программа, которая что-то делает, а проект — это группа приложений.

Итак, приступим к созданию приложения. Это делается следующим образом: python manage.py startapp riddles.
Как только приложение создано, давайте напишем простой вид, по правилам Django все виды должны храниться в файле views.py.

riddles/views.py

from django.http import HttpResponse


def index(request):
return HttpResponse("Hello, World!")

Теперь, чтобы привязать наш вид к URL, создадим файл urls.py.

riddles/urls.py

from django.conf.urls import url

from . import views

app_name = 'riddles'

urlpatterns = [
url(r'^$', views.index, name='index'),
]

В urls.py мы должны написать следующее:

django_example/urls.py

from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
url(r'^riddles/', include('riddles.urls')),
url(r'^admin/', admin.site.urls),
]

Теперь, если мы запустим наше приложение http://127.0.0.1:8000/riddles/, мы увидим «Hello, World!».

Установка базы данных


По умолчанию в Django используется SQLite, если она вас не устраивает, то вы

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

с нашей статьей, в которой мы рассказываем, как безболезненно перейти с SQLite на MySQL.

Теперь откроем django_example/settings.py и взглянем на переменную INSTALLED_APPS, она хранит все приложения, которые активны в текущем проекте. По умолчанию она содержит:

  • django.contrib.admin — админка, скоро мы ей воспользуемся.
  • django.contrib.auth — система аутентификации.
  • django.contrib.contenttypes — фреймворк для content types.
  • django.contrib.sessions — сессионный фреймворк.
  • django.contrib.messages — фреймворк для отправки сообщений.
  • django.contrib.staticfiles — фреймворк для работы со статичными файлами.

Некоторые из этих приложений используют базы данных, но они еще не установлены, поэтому мы и видели «You have unapplied migrations; your app may not work properly until they are applied.». Поправить это можно следующим образом: python manage.py migrate. Вы должны увидеть следующее:

Operations to perform:
Apply all migrations: admin, sessions, auth, contenttypes
Running migrations:
Rendering model states... DONE
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying sessions.0001_initial... OK

Теперь создадим нашу модель. Для начала создадим Riddle и Option. В Riddle будет содержаться загадка, в Option — один из возможных ответов на нее.

riddles/models.py

from django.db import models


class Riddle(models.Model):
riddle_text = models.CharField(max_length=255)
pub_date = models.DateTimeField('date published')


class Option(models.Model):
riddle = models.ForeignKey(Riddle, on_delete=models.CASCADE)
text = models.CharField(max_length=255)
correct = models.BooleanField(default=False)

Данная модель обеспечивает Django информацией, необходимой для создания схемы базы данных и database-access API для доступа к объектам. Теперь нам нужно привязать наше приложение к нашему проекту, делается это следующим образом:

django_example/settings.py

INSTALLED_APPS = [
'riddles.apps.RiddlesConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]

После этого нужно сделать миграцию: python manage.py makemigrations riddles. Вы должны увидеть следующее:

Migrations for 'riddles':
0001_initial.py:
- Create model Option
- Create model Riddle
- Add field riddle to option

Так мы говорим Django, что в моделях были сделаны некоторые изменения, и их нужно сохранить в качестве миграции.

Проверить, что сделает миграция, можно так: python manage.py sqlmigrate riddles 0001 (0001 — версия миграции, которую мы хотим проверить). На выходе мы получим:

BEGIN;
--
-- Create model Option
--
CREATE TABLE "riddles_option" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "text" varchar(255) NOT NULL, "correct" bool NOT NULL);
--
-- Create model Riddle
--
CREATE TABLE "riddles_riddle" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "riddle_text" varchar(255) NOT NULL, "pub_date" datetime NOT NULL);
--
-- Add field riddle to option
--
ALTER TABLE "riddles_option" RENAME TO "riddles_option__old";
CREATE TABLE "riddles_option" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "text" varchar(255) NOT NULL, "correct" bool NOT NULL, "riddle_id" integer NOT NULL REFERENCES "riddles_riddle" ("id"));
INSERT INTO "riddles_option" ("riddle_id", "id", "text", "correct") SELECT NULL, "id", "text", "correct" FROM "riddles_option__old";
DROP TABLE "riddles_option__old";
CREATE INDEX "riddles_option_a7c97949" ON "riddles_option" ("riddle_id");

COMMIT;

Заметьте, что команда sqlmigrate нужна только для проверки, каждый раз ее запускать необязательно.


Теперь мы можем начать пользоваться панелью администратора. Но для этого нам нужен пользователь. Создать его можно следующим образом: python manage.py createsuperuser. После этого запускаем сервер, если он не запущен, и переходим на http://127.0.0.1:8000/admin/. Вы увидите следующее:


Теперь дадим админу возможность изменять наши модели. Делается это так:

riddles/admin.py

from django.contrib import admin

from .models import Option, Riddle

admin.site.register(Riddle)
admin.site.register(Option)

Вот что получится в итоге:



Возьмите небольшую паузу и поиграйтесь с панелью администратора. Вы будете приятно удивлены тем, что умеет Django.

Главная страница


Что нам нужно для создания главной страницы?

  • Templates: скелет нашей страницы.
  • Views: функция на Python для отображения контента.

Начнем с шаблонов. Создадим папку templates внутри папки riddle, а в ней создадим index.html.

riddles/templates/index.html

<h1>Available Riddles</h1>

{% if message %}
<p><strong>{{ message }}</strong></p>
{% endif %}

{% if latest_riddles %}

<ul>
{% for riddle in latest_riddles %}
<li>
<a href="/riddles/{{ riddle.id }}/">
{{ riddle.riddle_text }}
</a>
</li>
{% endfor %}
</ul>

{% else %}
<p>No riddles are available right now.</p>
{% endif %}

Теперь создадим макет для ответов:

riddles/templates/answer.html

<h1>{{ riddle.riddle_text }}</h1>

{% if error_message %}
<p>
<strong>{{ error_message }}</strong>
</p>
{% endif %}

<form action="answer' riddle.id %}" method="post">
{% csrf_token %}
{% for option in riddle.option_set.all %}
<input type="radio" name="option" id="option{{ forloop.counter }}" value="{{ option.id }}" />
<label for="option{{ forloop.counter }}">{{ option.text }}</label><br>
{% endfor %}
<input type="submit" value="Answer" />
</form>

Здесь мы используем csrf_token, он нужен для защиты от

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

, каждая внутренняя форма должна его использовать. Теперь напишем виды для рендеринга наших шаблонов:

riddles/views.py

from django.http.response import HttpResponse
from django.shortcuts import get_object_or_404, render

from .models import Riddle, Option


def index(request):
return render(request, "index.html", {"latest_riddles": Riddle.objects.order_by('-pub_date')[:5]})


def detail(request, riddle_id):
return render(request, "answer.html", {"riddle": get_object_or_404(Riddle, pk=riddle_id)})


def answer(request, riddle_id):
riddle = get_object_or_404(Riddle, pk=riddle_id)
try:
option = riddle.option_set.get(pk=request.POST['option'])
except (KeyError, Option.DoesNotExist):
return render(request, 'answer.html', {'riddle': riddle, 'error_message': 'Option does not exist'})
else:
if option.correct:
return render(request, "index.html", {"latest_riddles": Riddle.objects.order_by('-pub_date')[:5], "message": "Nice! Choose another one!"})
else:
return render(request, 'answer.html', {'riddle': riddle, 'error_message': 'Wrong Answer!'})

Давайте пройдемся по каждой функции отдельно:

  • index: Index использует функцию render. На вход она получает HttpRequest, местонахождение шаблона и его содержимое, а возвращает HttpResponse с окончательным html.
  • detail: Detail делает практически то же самое, но только функция get_object_or_404 возвращает HttpResponse404, если нужный объект не был найден.
  • answer: Answer ищет предоставленную загадку (и возвращает 404, если она не найдена) и проверяет правильность ответа.

Теперь добавим наши функции в urls.py:

riddles/urls.py

from django.conf.urls import url

from . import views

app_name = 'riddles'

urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^(?P[0-9]+)/$', views.detail, name='detail'),
url(r'^(?P[0-9]+)/answer/$', views.answer, name='answer')
]

Добавим немного стилей


Для начала создадим директорию static, а в ней создадим файл min.css.

riddles/static/min.css

body{
margin:40px auto;
max-width:650px;
line-height:1.6;
font-size:18px;
color:#444;
padding:0 10px;
}
h1,h2,h3{
line-height:1.2;
text-align: center;
}
a {
color: blue;
}

form {
margin: 0 auto;
padding: 1em;
border: 1px solid #CCC;
border-radius: 1em;
}
form div + div {
margin-top: 1em;
}
label {
display: inline-block;
text-align: center;
width: 40%;
}
input {
font: 1em sans-serif;
-moz-box-sizing: border-box;
box-sizing: border-box;
border: 1px solid #999;
width: 50%;
}
input:focus {
border-color: #000;
}
p, div.button {
text-align: center;
}

p.error-message {
color: lightcoral;
}

Немного изменим наши шаблоны:

riddles/templates/index.html

{% load staticfiles %}

<link rel="stylesheet" type="text/css" href="{% static 'main.css' %}" />

<h1>Available Riddles</h1>

{% if message %}
<p><strong>{{ message }}</strong></p>
{% endif %}

{% if latest_riddles %}

<ul>
{% for riddle in latest_riddles %}
<li>
<a href="/riddles/{{ riddle.id }}/">
{{ riddle.riddle_text }}
</a>
</li>
{% endfor %}
</ul>

{% else %}
<p>No riddles are available right now.</p>
{% endif %}

riddles/templates/answer.html

{% load staticfiles %}

<link rel="stylesheet" type="text/css" href="{% static 'main.css' %}" />

<h1>{{ riddle.riddle_text }}</h1>

{% if error_message %}
<p>
<strong>{{ error_message }}</strong>
</p>
{% endif %}

<form action="answer' riddle.id %}" method="post">
{% csrf_token %}
{% for option in riddle.option_set.all %}
<input type="radio" name="option" id="option{{ forloop.counter }}" value="{{ option.id }}" />
<label for="option{{ forloop.counter }}">{{ option.text }}</label><br>
{% endfor %}
<input type="submit" value="Answer" />
</form>

Первая строка загружает статические файлы, потом мы используем {% static '#' %}, где # — путь к вашему файлу. Аналогичная процедура проводится и для JavaScript.

Теперь вы можете создавать свои собственные приложения на Django.

Исходный код нашего приложения можно скачать по этой

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

.

Запись

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

впервые появилась

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

.
 
Вверх