Вы находитесь на странице: 1из 13

СРЕДА РАЗРАБОТКИ И ВЫБОР ВЕРСИЙ

Как уже было сказано выше, для разработки проекта в качестве


серверного языка программирования будет использован Python с
фреймворком Django.

На данный момент, крайней релизной версией Python является Python


3.9, однако для разработки будет использована версия 3.7.2, для лучшей
совместимости с хостингом и отдельными библиотеками. Данная версия
была загружена с официального сайта.

Версией Django, используемой в проекте, является актуальная на


текущий момент – 3.1.4. Данный фреймврок был загружен при помощи
встроенной в Python менеджер пакетов – PIP с помощью консольной
команды:

pip install django.

Поскольку Python является интерпретируемым языком, он не требует


специфических компиляторов, что позволяет выполнять исходный код вне
сред разработки, запустив файл с кодом через консоль. Данный факт также
снимает необходимость использовать серьезные среды разработки, однако в
случае разработки серьезных приложений, они зачастую, все же являются
необходимыми.

В качестве среды разработки для данного проекта будет использована


PyCharm. Данная среда разработки позволяет создавать шаблоны проектов,
отображает дерево файлов и позволяет выполнять написанный код во
встроенном терминале.

Во время разработки, будет использована база данных sqlite3, входящая


в состав Django. После развертывания проекта на хостинге, он будет
использовать Postgresql.
ОБЩАЯ СТРУКТУРА DJANGO-ПРОЕКТА
В базовом представлении, структура пустого проекта представляет из
себя корневой каталог с папкой, содержащей три файла: settings.py, urls.py и
wsgi.py, дублирующей название проекта, а также файл manage.py. Ниже
приведены функциональные назначения данных файлов.

 settings.py содержит в себе все настройки проекта. Здесь мы


регистрируем приложения, задаём размещение статичных файлов,
настройки базы данных и так далее.
 urls.py задаёт ассоциации url адресов с представлениями. Несмотря на
то, что этот файл может содержать все настройки url, обычно его делят на
части, по одной на приложение, как будет показано далее.
 wsgi.py используется для налаживания связи между Django
приложением и веб-сервером.
 Manage.py используется для создания приложений, работы с базами
данных и для запуска отладочного сервера.

Также, любой для работы любого Django-проекта, необходимо как


минимум одно приложение – python-пакет, обладающий определенным
функционалом. Любое приложение состоит из моделей, представлений,
шаблонов и статичных файлов.

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

Manage.py startapp название проекта латиницей.

По выполнению данной команды в корневом каталоге будет создана


папка с названием приложения. По умолчанию, внутри создаются
следующие файлы: views.py, models.py, tests.py,apps.py,admin.py. Ниже
приведены функциональные назначения данных файлов.

 views.py содержит представления – python-функции, принимающие


web-запрос и возвращающие web-ответ.
 models.py содержит модели данных – структурные описания таблиц
базы данных.
 Apps.py содержит конфигурацию текущего приложения.
 Tests.py
 Admin.py содержит функции отображения моделей в базовой панели
администратора.

Также, опциональными файлами для приложения являются:

 forms.py, содержащий формы


 urls.py, задающий ассоциации url адресов с представлениями внутри
приложения.

А также папки templates, содержащую шаблоны html-страниц,


templatetags, содержащую шаблоны пользовательских тегов и migtations,
содержащую файлы миграций – функций переноса изменений в моделях в
базу данных.

СОЗДАНИЕ ОСНОВНОГО ПРИЛОЖЕНИЯ – MAIN


Оформление требований к приложению
Согласно требованиям к проекту, выдвинутым в первом разделе, он
должен позволять публиковать преподавателям лекции, диспетчерской
составлять и обновлять расписание онлайн занятий, а студентам читать
данные лекции и просматривать расписание для своей группы.

Основное приложение должно обеспечивать работоспособность сайта в


целом и обрабатывать запросы на уровне студента. Данную задачу можно
разделить на несколько отдельных задач:

 Отображение статических страниц:


o Главная
o Контактная информация
 Вывод списка лекций с разделением по:
o Дисциплинам
o Страницам (пагинация)
 Отображение конкретной лекции
 Оставление комментариев под лекциями
 Добавление лекции в закладки
 Форма запроса студентами лекций на определенную тематику
 Отображение расписания онлайн-занятий
 Отслеживание переходов по несуществующим адресам

Проанализировав данные задачи, можно выделить несколько моделей,


требующих реализации в данном приложении:

 Дисциплины
 Лекции
 Комментарии
 Заявки
 Расписание

Также, можно выделить следующие типовые страницы:

 Главная
 Контактная информация
 Лекции
 Конкретная лекция
 Расписание
 Шаблоны страниц для отображения ошибок (ошибки доступа,
ошибки адресации и т.д.)

Выдвинув все необходимые требования к приложению, можно


приступать к его программной реализации.
Реализация моделей приложения Main
Модель является единственным источником информации о данных.
Она содержит основные поля и поведение данных, которые хранятся в базе
денных. Как правило, каждая модель отображается в одну таблицу базы
данных.

Основы:

 Каждая модель представляет собой класс Python, который


является подклассом django.db.models.Model.
 Каждый атрибут модели представляет поле базы данных.
 При этом Django предоставляет вам автоматически
сгенерированный API доступа к базе данных;

Модели описываются в файле models.py.

Для корректной работы моделей, вверху файла следует подключить


определенные классы:

from django.db import models from django.db import models

Далее можно описывать необходимые модели.

Модель Дисциплина:

class Discipline(models.Model):
name = models.CharField('Название дисциплины', max_length=50)

class Meta:
verbose_name = "Дисциплина"
verbose_name_plural = 'Дисциплины'

def __str__(self):
return self.name
Рассмотрим отдельные элементы на примерах следующих моделей:

class Discipline(models.Model)

Здесь объявляется новый класс модели - Discipline, который


наследуется от базового класса Model.

name = models.CharField('Название дисциплины', max_length=50)


Здесь описывается поле “Название дисциплины”, объявляется его тип и
максимальная длинна. В целом, поля, объявляемые здесь, идинтчны тем, что
можно добавить непосредственно в базе данных. Стоит, однако, отметить,
что при описывании модели, первичный ключ не объявляется – API
генерирует его автоматически во время миграции.

class Meta:
verbose_name = "Дисциплина"
verbose_name_plural = 'Дисциплины'

Вложенный класс Meta позволяет назначать базе имя в единственном и


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

def __str__(self):
return self.name

Данный метод класса возвращает определенное поле, при выводе всех


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

Модель Лекция

class Lecture(models.Model):
discipline = models.ForeignKey(Discipline,on_delete=models.CASCADE,null=True)
title = models.CharField('Название лекции', max_length=150)
text = models.TextField('Текст лекции')
date = models.DateField('Дата публикации',auto_now=True)

class Meta:
verbose_name = 'Лекция'
verbose_name_plural = 'Лекции'

def __str__(self):
return self.title
В данной модели представлено несколько новых полей. Прежде всего,
это внешний ключ от модели Дисциплина. При его объявлении добавляется
несколько важных атрибутов – прежде всего on_delete, который описывает
поведение записей при удалении оригинального ключа. В данном случае, при
удалении определенного ключа, удаляются и все связанные с ним записи.
Также, здесь добавляется атрибут null, положительное значение которого
позволяет сохранять записи вообще без внешнего ключа.
Еще одним новым полем является поле date, которое хранит время
публикации. Атрибут auto_now позволяет проставлять дату автоматически.

Модель Комментарий

class Comment(models.Model):
lecture = models.ForeignKey(Lecture, on_delete=models.CASCADE)
autor_name = models.CharField('Имя автора', max_length=50)
comment_text = models.TextField('Текст комментария')
class Meta:
verbose_name = 'Комментарий'
verbose_name_plural = 'Комментарии'
def __str__(self):
return self.comment_text
Модель Расписание

class Shelude(models.Model):
Group = models.ForeignKey(Group,on_delete=models.PROTECT, null=True)
Day = models.ForeignKey(Day, on_delete=models.PROTECT, null=True)
first_lect = models.ForeignKey(Discipline, on_delete=models.PROTECT, related_name= 'first_lect',
verbose_name='Первая пара', blank=True, null=True)
second_lect = models.ForeignKey(Discipline, on_delete=models.PROTECT, related_name='second_lect',
verbose_name='Вторая пара', blank=True, null=True)
thrid_lect = models.ForeignKey(Discipline, on_delete=models.PROTECT, related_name='thrid_lect',
verbose_name='Третья пара', blank=True, null=True)
four_lect = models.ForeignKey(Discipline, on_delete=models.PROTECT, related_name='four_lect',
verbose_name='Четвертая пара', blank=True, null=True)
five_lect = models.ForeignKey(Discipline, on_delete=models.PROTECT, related_name='five_lect',
verbose_name='Пятая пара', blank=True,null=True)

def __str__(self):
return self.Group.group_num

class Meta:
verbose_name = 'Расписание'
verbose_name_plural = 'Расписания'
unique_together = ('Group', 'Day')
В данной модели присутствует несколько внешних ключей к одной
таблице. Это допустимый случай – во время миграции API автоматически
преобразовывает их в допустимые и автоматически обрабатывает запросы к
ним.

В во вложенном классе Meta прописывается условие “уникальное


вместе”. Оно не позволяет создавать записи с несколькими идентичными
полями. В данном случае такими полями выступают номер группы и день,
когда проводиться пара.
После создания моделей, следует провести Миграции – процесс
преобразования моделей в таблицы в базе данных. Для этого следует
прописать в консоли две команды:

 manage.py makemigrations
 manage.py migrate

Реализация представлений приложения Main


Представления в Django – это python-функции, принимающие web-
запрос и возвращающие web-ответ. Ответом может быть HTML-содержимое
страницы, или перенаправление, или 404 ошибка, или XML-документ, или
изображение. Представление содержит всю необходимую логику для
создания ответа.

В Django представления также позволяют реализовать функционал


сходный ajax-запросам, используя стандартные функции. В частности,
подобные возможности используются для работы с формами.

Для отображения шаблонов, следует подключить модуль под


названием render, который позволяет отображать html-страницы.

from django.shortcuts import render

В самом простом случае, представление просто загружают статичную


страницу. В главном приложении такими страницами являются страницы
«Главная» и «Контактная информация»:

def index(request):
return render(request, 'main/index.html')

def about(request):
return render(request, 'main/about.html')
Также, помимо простого отображения страницы, представления могут
передавать данные из базы данных. Поскольку Django представлен с учетом
концепции MVC (Model-View-Controller/ модель-представление-контроллер),
при обращении к базе данных нет необходимости писать sql-запрос,
достаточно обратится к ее модели. Рассмотрим представление, выводящее на
страницу конкретную статью:

def lections_detail(request, lecture_id):


try:
lect = Lecture.objects.get(id=lecture_id)
except:
raise Http404('Статья не найдена')
return render(request, 'main/currect_lecturies.html', {'lecture': lect})
Для получения данных достаточно обратиться к соответствующей
модели:

lect = Lecture.objects.get(id=lecture_id)

При этом можно запрашивать как единственный конкретный объект


при помощи метода get() с указанием фильтра, так и набор строк, используя
метод filter() и так-же указывая необходимый параметр. Для вывода всех
объектов следует использовать метод all() без параметров.

Далее полученные данные отправляются на выводимую страницу при


помощи рендера.

return render(request, 'main/currect_lecturies.html', {'lecture': lect})

Помимо простого вывода данных из таблицы, представления могут


обрабатывать данные из форм. При этом не имеет значения, каким методом
передаются данные.

Рассмотрим данную возможность на примере представления для


вывода расписания:

def shelude(request):
grp = Group.objects.first()
group_id = grp.idgroup_id = 1
if request.method == "POST":
group = groupForm(request.POST)

if group.is_valid():
group_id = request.POST.get('group')
print(group)

group = groupForm()

forms = {
'group':group
}
group = Group.objects.get(id=group_id)

pn = Shelude.objects.filter(Group=group_id, Day=1)
vt = Shelude.objects.filter(Group=group_id, Day=2)
sr = Shelude.objects.filter(Group=group_id, Day=3)
ch = Shelude.objects.filter(Group=group_id, Day=4)
pt = Shelude.objects.filter(Group=group_id, Day=5)
return render(request, 'main/shelide.html',{'pon':pn,'vt':vt,'sr':sr,'chet':ch,'pt':pt, 'forms':forms,'group':group})
По умолчанию выводиться расписание для первой группы в базе:

grp = Group.objects.first()
group_id = grp.idgroup_id = 1
Однако, если к представлению обращаются при помощи метода POST,
вызываемого срабатыванием формы и заполненная форма верна, то
полученные из нее данные подставляются в фильтр:

if request.method == "POST":
if group.is_valid():
group_id = request.POST.get('group')
***
group = Group.objects.get(id=group_id)
pn = Shelude.objects.filter(Group=group_id, Day=1)
***

Еще одной возможностью представлений, является постраничное


представление или так называемая пагинация. Данная возможность
используется для удобства восприятия и уменьшения ресурсоемкости
загружаемой страницы.

def lections(request):
Lectures = Lecture.objects.all()
Disciplines = Discipline.objects.all()

paginator = Paginator(Lectures,2)
page_num = request.GET.get('page',1)
page_objects = paginator.get_page(page_num)

Seach = seachForm()
forms = {
'Seach': Seach,

return render(request, 'main/lectures.html', {'Lectures': Lectures, 'Disciplines':


Disciplines,'page_obj':page_objects,'forms':forms})
Данная возможность применяется для отображения больших массивов
данных, которыми в данном проекте является список лекций.

Для этого нужно в начале файла подключить класс Paginator:

from django.core.paginator import Paginator

Далее все объекты из запроса передаются в новый объект данного класса:

Lectures = Lecture.objects.all()
paginator = Paginator(Lectures,2)
После этого при помощи GET-запроса получается номер страницы и на
основе этого номера выбирается список строк.

page_num = request.GET.get('page',1)
page_objects = paginator.get_page(page_num)

def categories(request,discioline_id):
Disciplines = Discipline.objects.all()
Lectures = Lecture.objects.all().filter(discipline = discioline_id)
Discipline_name = Discipline.objects.get(id=discioline_id)

paginator = Paginator(Lectures, 2)
page_num = request.GET.get('page', 1)
page_objects = paginator.get_page(page_num)

return render(request, 'main/lectures.html', {'Lectures': Lectures, 'Disciplines': Disciplines,'Descipline_id':


discioline_id,'page_obj':page_objects, 'Discipline_name':Discipline_name})

def seach(request):
Lectures = Lecture.objects.all()
Disciplines = Discipline.objects.all()
error = ''
lectures = ''
seach_q = '2'
if request.method == "POST":
Seach = seachForm(request.POST)

if Seach.is_valid():
seach_q = request.POST.get('seach')
print(seach_q)

Lectures = Lecture.objects.filter(title__icontains=seach_q)
paginator = Paginator(Lectures, 2)
page_num = request.GET.get('page', 1)
page_objects = paginator.get_page(page_num)

Seach = seachForm()
forms = {
'Seach': Seach,

}
return render(request,'main/lectures.html',{ 'forms':forms,'Seach_q': seach_q,
'letc':lectures,'Seach':Seach,'page_obj':page_objects})

def comment(request, lecture_id):


try:
lect = Lecture.objects.get(id=lecture_id)
except:
raise Http404()
if request.method == 'GET':
name = request.GET['name']
text = request.GET['textf']
lect.comment_set.create(autor_name=name, comment_text=text)
return HttpResponseRedirect(reverse('main:Curr_lecture', args=(lect.id,)))

def error_404 (request,exception):


render(request, '404.html')

Создание шаблонов страниц в приложении Main


Главный слоган Django – «не повторяй себя». В полной мере он
раскрывается в работе с шаблонами – основным методом отображения
данных в Django. Они позволяют избежать повторяющегося кода и
упрощают создание страниц схожего строения.

Шаблоны хранятся в папке templates каталога приложения, однако при


необходимости могут быть вызваны и из другого.

Рассмотрим создание ша

<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title> {% block Title %}{% endblock %}</title>
<link rel="stylesheet" href="{% static "css/main.css" %}" />
</head>
<body>
<header>
<div class="top-menu">
<ul >
<li><a href="{% url 'main:home' %}">Главная</a></li>
<li><a href="{% url 'main:lections' %}">Лекции</a></li>
<li><a href="{% url 'main:shelude' %}">Расписание</a></li>
<li><a href="{% url 'main:about' %}">Контакты</a></li>
</ul>
</div>
</header>
<div class="falsh"></div>
<div class="content">
{% block Content %}{% endblock %}
</div>
<footer class="footer">1</footer>
</body>
</html>

Вам также может понравиться