Приветствую.
Прошел очередной месяц... А значит пора писать новый пост на Pikabu.
Обучение: шестнадцатый месяц
Как обычно, жду лайков, репостов и вот это всё)
Прошел очередной месяц... А значит пора писать новый пост на Pikabu.
Обучение: шестнадцатый месяц
Как обычно, жду лайков, репостов и вот это всё)
🔥6👍2
Django 37. Две формы - добавление категории и файла
Автор: Иван Ашихмин
В прошлом посте мы написали форму добавления поста автором.
В этом посте добавим две формы: добавление новой категории и добавления файла для поста.
В процессе работы мы закрепим создание форм, создадим три представления, применив наследование, а также создадим два шаблона.
Автор: Иван Ашихмин
В прошлом посте мы написали форму добавления поста автором.
В этом посте добавим две формы: добавление новой категории и добавления файла для поста.
В процессе работы мы закрепим создание форм, создадим три представления, применив наследование, а также создадим два шаблона.
🔥1
Однако есть и второй вариант, а именно создание нового связанного объекта (в нашем случае категория и файл поста) прямо на странице добавления нового поста. Примерно также, как это реализовано в панели администратора Django. Подробнее можно прочитать в посте на Boosty "Django - Добавление новой категории в форме создания поста без перезагрузки страницы" (платный контент).
Формы добавления категории и файла поста.
Откроем файл
Форма добавления категории.
Создадим новый класс
Так же, как мы делали в посте "Django 36. Добавление постов пользователем", создаём конструктор класса
В нём добавляем всем полям формы bootstrap-класс
Обратите внимание, в прошлом посте мы делали поле необязательным к заполнению для корректной работы редактора. В этот раз поле необязательно по умолчанию, поэтому пропускаем этот параметр.
Далее создаём подкласс
Код формы:
Форма добавления файла.
Форма такая же, как и предыдущая. Исключение составляет только отсутствие дополнительного класса для поля, модель и сам список полей формы
Код формы:
Представления страницы добавления категории и страницы добавления файла поста.
Откроем файл
Прочитав вступление, вы можете задаться вопросом: "зачем нам три представления, если будет две формы?". Всё верно, мы создадим три представления, а не два.
В посте "Django 27.1 Представления на основе классов" я описывал преимущества классовых представлений, одно из них - наследование.
Оба представления практически идентичны, отчего было бы разумнее сделать общий класс представления и уже от него наследовать два конкретных представления для страниц.
Базовый класс.
Создадим класс
В теле класса будет всего два метода:
Формы добавления категории и файла поста.
Откроем файл
forms.py в директории приложения user_app.Форма добавления категории.
Создадим новый класс
AddCategoryByAuthorForm, унаследованный от ModelForm.Так же, как мы делали в посте "Django 36. Добавление постов пользователем", создаём конструктор класса
__init__.В нём добавляем всем полям формы bootstrap-класс
form-control и дополнительный класс для поля description - django_ckeditor_5, для работы визуального редактора Django CKEditor 5.Обратите внимание, в прошлом посте мы делали поле необязательным к заполнению для корректной работы редактора. В этот раз поле необязательно по умолчанию, поэтому пропускаем этот параметр.
Далее создаём подкласс
Meta, прописываем модель и необходимые поля.Код формы:
from blog.models import CategoryModel
class AddCategoryByAuthorForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields:
self.fields[field].widget.attrs.update({'class': 'form-control', 'autofocus': ''})
self.fields['description'].widget.attrs.update({'class': 'django_ckeditor_5'})
class Meta:
model = CategoryModel
fields = ('title', 'parent', 'description', 'telegram_link')
Форма добавления файла.
Форма такая же, как и предыдущая. Исключение составляет только отсутствие дополнительного класса для поля, модель и сам список полей формы
Код формы:
from blog.models import PostFilesModel
class AddFileByAuthorForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields:
self.fields[field].widget.attrs.update({'class': 'form-control', 'autofocus': ''})
class Meta:
model = PostFilesModel
fields = ('title', 'file')
Представления страницы добавления категории и страницы добавления файла поста.
Откроем файл
views.py в директории приложения user_app.Прочитав вступление, вы можете задаться вопросом: "зачем нам три представления, если будет две формы?". Всё верно, мы создадим три представления, а не два.
В посте "Django 27.1 Представления на основе классов" я описывал преимущества классовых представлений, одно из них - наследование.
Оба представления практически идентичны, отчего было бы разумнее сделать общий класс представления и уже от него наследовать два конкретных представления для страниц.
Базовый класс.
Создадим класс
AddCategoryAndFile с двойным наследованием: UserPassesTestMixin и CreateView.В теле класса будет всего два метода:
🔥1
test_func - для проверки того, что пользователь входит в группу "Автор". Подробнее об этом рассказывал в прошлом посте - "Django 36. Добавление постов пользователем".get_success_url - метод, определяющий куда будет перенаправлен пользователь после заполнения формы. В нашем случае на страницу профиля.Это всё, что будет в нашем классе. Остальные параметры будут заменены в классах-наследниках.
Код класса:
from django.contrib.auth.mixins import UserPassesTestMixin
from django.views.generic import CreateView
class AddCategoryAndFile(UserPassesTestMixin, CreateView):
def test_func(self):
return self.request.user.groups.filter(name='Автор').exists()
def get_success_url(self):
return reverse('user_app:user_profile', kwargs={'username': self.request.user.username})
Представление добавления файла.
Создадим класс
AddFileView, унаследованный от нашего класса AddCategoryAndFile.В этом представлении не будет методов, только четыре поля:
template_name - шаблон страницы.form_class - класс формы.model - используемая модель.extra_context - дополнительные данные, в нашем случае это заголовок страницы.Это весь класс.
Код класса:
from blog.models import PostFilesModel
class AddFileView(AddCategoryAndFile):
template_name = 'user_app/add_file.html'
form_class = forms.AddFileByAuthorForm
model = PostFilesModel
extra_context = {'title': 'Добавление файла'}
Представление добавления категории.
Создадим класс
AddCategoryView, унаследованный от нашего класса AddCategoryAndFile.В этом представлении будут точно такие же поля, как и в предыдущем, а также один метод:
form_valid - в этом методе мы приводим поле slug к корректному виду. Почему это важно сделать, я объяснял в прошлом посте.Код класса:
from blog.models import CategoryModel
class AddCategoryView(AddCategoryAndFile):
template_name = 'user_app/add_category.html'
form_class = forms.AddCategoryByAuthorForm
model = CategoryModel
extra_context = {'title': 'Добавление категории'}
def form_valid(self, form):
form.instance.slug = slugify(form.instance.title)
return super().form_valid(form)
URL-паттерны.
Откроем файл
urls.py в директории приложения user_app и в список urlpatterns добавим следующие строки:path('post/add_category/', views.AddCategoryView.as_view(), name='add_category'),
path('post/add_file/', views.AddFileView.as_view(), name='add_file'),Шаблоны страниц.
В директории с шаблонами приложения
user_app создадим два файла:add_category.html - файл с формой добавления категории.add_file.html - файл с формой добавления файла поста.Оба шаблона практически идентичны.
Различия заключаются в том, что в форме добавления категории выводится
{{ form.media }} для отображения визуального редактора, а в форме добавления файла указано enctype="multipart/form-data", означающее, что форма может передавать файлы.Код страницы добавления категории:
🔥1
{% extends 'blog/base.html' %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<div class="container mt-3 d-flex justify-content-center">
<div class="col-lg-8 col-sm-12">
<h2>{{ title }}</h2>
<form method="post">
{% csrf_token %}
{{ form.media }}
{{ form.as_p }}
<button type="submit" class="btn btn-primary my-btn-success mt-3">Сохранить</button>
</form>
</div>
</div>
{% endblock %}Код страницы добавления файла:
{% extends 'blog/base.html' %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<div class="container mt-3 d-flex justify-content-center">
<div class="col-lg-8 col-sm-12">
<h2>{{ title }}</h2>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary my-btn-success mt-3">Сохранить</button>
</form>
</div>
</div>
{% endblock %}Добавляем ссылки в меню пользователя.
Откройте файл
header.html и под ссылкой на добавление нового поста добавьте следующий код:<li>
<a class="dropdown-item dd-item-color" href="{% url 'user_app:add_category' %}">Добавить
категорию</a>
</li>
<li>
<a class="dropdown-item dd-item-color" href="{% url 'user_app:add_file' %}">Добавить
файл</a>
</li>
Заключение.
Довольно часто приходится создавать однотипные классы, страницы или просто использовать одни и те же фрагменты кода несколько раз.
Для решения проблемы ненужного "раздувания" кода - отлично подходит наследование и создание базовых классов.
Если вас заинтересует другой способ реализации подобного функционала (не в виде отдельных страниц, а непосредственно в форме добавления поста), то об этом я рассказываю в посте на Boosty "Django - Добавление новой категории в форме создания поста без перезагрузки страницы" (платный контент).
В следующем посте мы продолжим эту тему и затронем такие конструкции, как декораторы и миксины.
Файлы к посту, можно получить в боте по коду: 821104
Пост на сайте
Поддержать проект
#Django #Гайды #ООП #формы #представления #Код_на_салфетке #наследования #классы
🔥3
Django - Добавление новой категории в форме создания поста без перезагрузки страницы
Автор: Иван Ашихмин
Встроенная панель администратора - одно из главных преимуществ фреймворка Django. Это весьма функциональный и удобный инструмент. Одна из его возможностей - это добавление связанного с моделью объекта на странице создания этого самого объекта.
Например, у нас есть модель поста с внешним ключом к модели категории. Открыв страницу создания нового поста в панели администратора, мы можем добавить новую категорию не теряя заполненные данные, не переключаясь на другие страницы.
С появлением первых постов на канале ко мне обратились с вопросом: "Возможно ли реализовать функционал из панели администратора на страницах сайта?". Это меня заинтересовало, но ввиду того, что не было необходимости, решение данной задачи было отложено. При создании функционала для авторов я вернулся к этому вопросу.
Автор: Иван Ашихмин
Встроенная панель администратора - одно из главных преимуществ фреймворка Django. Это весьма функциональный и удобный инструмент. Одна из его возможностей - это добавление связанного с моделью объекта на странице создания этого самого объекта.
Например, у нас есть модель поста с внешним ключом к модели категории. Открыв страницу создания нового поста в панели администратора, мы можем добавить новую категорию не теряя заполненные данные, не переключаясь на другие страницы.
С появлением первых постов на канале ко мне обратились с вопросом: "Возможно ли реализовать функционал из панели администратора на страницах сайта?". Это меня заинтересовало, но ввиду того, что не было необходимости, решение данной задачи было отложено. При создании функционала для авторов я вернулся к этому вопросу.
🔥2
В этом посте будем продолжать написанное в "Django 37. Две формы - добавление категории и файла", а именно, добавим возможность создать новую категорию или добавить новый файл без перезагрузки страницы.
Продолжение в посте на Boosty (платный контент)
Пост на сайте
Поддержать проект
#Django #Гайды #ООП #формы #представления #Код_на_салфетке #наследования #классы #Boosty
Продолжение в посте на Boosty (платный контент)
Пост на сайте
Поддержать проект
#Django #Гайды #ООП #формы #представления #Код_на_салфетке #наследования #классы #Boosty
🔥2
Зарождение проекта...
Автор: Некий Вестник Сплетен
Итак, начнём сначала..
Чат "Кот на салфетке" объединил в себе множество разных людей с отличающимися характерами и интересами, разного возраста и географии. Но всех нас объединяет любовь к программированию. Здесь общение происходит абсолютно на разные темы.. И это прекрасно! В обычное время это выглядит слегка "безумно" и человек "со стороны" может испугаться или счесть нас сумасшедшими. Но порой здесь можно встретить интересные темы, задачи, идеи.
В один из вечеров поступило предложение сделать групповой проект и даже была предложена идея, что-то связанное с фанфиками. Один из участников обсуждения вызвался подготовить ТЗ для проекта, остальные поддержали его инициативу и стали ждать. Прошёл день, два, три.. Но ТЗ так и не было начато. Выяснилось, что у "желающего" не стало на это времени. Периодами разговоры снова возрождались и снова затихали.
Автор: Некий Вестник Сплетен
Итак, начнём сначала..
Чат "Кот на салфетке" объединил в себе множество разных людей с отличающимися характерами и интересами, разного возраста и географии. Но всех нас объединяет любовь к программированию. Здесь общение происходит абсолютно на разные темы.. И это прекрасно! В обычное время это выглядит слегка "безумно" и человек "со стороны" может испугаться или счесть нас сумасшедшими. Но порой здесь можно встретить интересные темы, задачи, идеи.
В один из вечеров поступило предложение сделать групповой проект и даже была предложена идея, что-то связанное с фанфиками. Один из участников обсуждения вызвался подготовить ТЗ для проекта, остальные поддержали его инициативу и стали ждать. Прошёл день, два, три.. Но ТЗ так и не было начато. Выяснилось, что у "желающего" не стало на это времени. Периодами разговоры снова возрождались и снова затихали.
🔥4
...Прошло две недели...
Так не могло продолжаться дальше. Не допустимо было допускать это откладывание, оттягивание и отсутствие собранности.
Тогда было решено создать отдельный чат и приступить к работе уже непосредственно с теми, кто желает этим заниматься. Создали чат, нарекли его на временной основе - "Некий проект", разместили ссылку в "Коте на салфетке", по которой желающие участвовать в проекте могли присоединиться самостоятельно.
Таким образом, собралась команда из 14 человек:
9 Backend-разработчиков
2 Frontend-разработчика
2 UX/UI-дизайнера
1 Project-менеджер
И началась череда созвонов...
Пост на сайте
Поддержать проект
#Кот_на_салфетке #Backend #Код_на_салфетке #Некий_проект #UI #созвоны #групповой_проект #UX #Frontend #Project
Так не могло продолжаться дальше. Не допустимо было допускать это откладывание, оттягивание и отсутствие собранности.
Тогда было решено создать отдельный чат и приступить к работе уже непосредственно с теми, кто желает этим заниматься. Создали чат, нарекли его на временной основе - "Некий проект", разместили ссылку в "Коте на салфетке", по которой желающие участвовать в проекте могли присоединиться самостоятельно.
Таким образом, собралась команда из 14 человек:
9 Backend-разработчиков
2 Frontend-разработчика
2 UX/UI-дизайнера
1 Project-менеджер
И началась череда созвонов...
Пост на сайте
Поддержать проект
#Кот_на_салфетке #Backend #Код_на_салфетке #Некий_проект #UI #созвоны #групповой_проект #UX #Frontend #Project
🔥5
Приветствую.
На канале сейчас активна только одна рубрика с гайдами и та посвящена Django. Помимо есть три информационные: про питон, про стажировку и про наш групповой проект.
Нужна ваша помощь. На какую тему вы бы хотели видеть гайды кроме Джанго?
Пишите в комментарии общую технологию или конкретные библиотеки, идеи или вещи.
Спасибо.
На канале сейчас активна только одна рубрика с гайдами и та посвящена Django. Помимо есть три информационные: про питон, про стажировку и про наш групповой проект.
Нужна ваша помощь. На какую тему вы бы хотели видеть гайды кроме Джанго?
Пишите в комментарии общую технологию или конкретные библиотеки, идеи или вещи.
Спасибо.
Начало работ
Автор: Иван Ашихмин
Прошел месяц с начала стажировки.
Первые пару недель заняли организационные вопросы:
- Формирование команд - Наш проект единственный разрабатывается на Django + VueJS, поэтому формирование команды не заняло много времени.
- Чаты - Сформировали чат всего проекта, а также чаты направлений.
- Доступы - Предоставили доступ к сервису Mattermost. Это такой "корпоративный чат" с разными "каналами", SCRUM-доской и так далее. Никогда с ним ранее не сталкивался, но, по словам организаторов, этот сервис используют многие IT-компании.
Автор: Иван Ашихмин
Прошел месяц с начала стажировки.
Первые пару недель заняли организационные вопросы:
- Формирование команд - Наш проект единственный разрабатывается на Django + VueJS, поэтому формирование команды не заняло много времени.
- Чаты - Сформировали чат всего проекта, а также чаты направлений.
- Доступы - Предоставили доступ к сервису Mattermost. Это такой "корпоративный чат" с разными "каналами", SCRUM-доской и так далее. Никогда с ним ранее не сталкивался, но, по словам организаторов, этот сервис используют многие IT-компании.
🔥5👍1
- Документы - На подписание дали два документа: Разрешение на обработку персональных данных и Соглашение о неразглашении (NDA). NDA в нашем случае с послаблениями, а именно, мы можем использовать собственно написанный код для предоставления работодателям или в обучающих целях. Тем не менее, публиковать полный код или результаты работы команды строго-настрого запрещено. Подписывал подобное в первый раз, предварительно связавшись с директором Академии LAD и уточнив, что мне можно рассказывать.
Потом была пара общих собраний, на которых в основном обсуждалась концепция проекта. Я на этих звонках сидел "ниже воды, тише травы", поскольку всё это для меня в новинку и, по правде говоря, мало что понимал в обсуждениях. Сидел, слушал, пытался уяснить и набирался опыта.
Объяснили, как работать в Mattermost и как будут распределяться задачи на SCRUM-доске. Придётся привыкать к нему, так как, не считая Telegram-чатов для "быстрого" реагирования, это должно стать основным место для обсуждений.
Продакты провели анализ конкурентов и предоставили варианты направления развития проекта.
Сейчас они продолжают исследования, для этого запустили опрос среди тех кто покупал курсы по обучению программированию себе или детям. Если есть желание помочь в исследовании, можете заполнить анкету по ссылке: https://docs.google.com/forms/d/e/1FAIpQLScmkxKpesSroNG0GYxuUS8ruOIjObQ1otITffpBoBPhFQvXBw/viewform
С бэками созванивались два раза.
Первый созвон был для знакомства с командой. На нём нужно было рассказать о себе. Я, конечно, волновался, потому что не очень понимал, что рассказать о себе. Но, послушав остальных, сумел кое-как рассказать о своем опыте и навыках. Команда подобралась разношерстная.
Второй созвон оказался интереснее и был посвящён обсуждению начала работы над проектом. Знания некоторых коллег впечатляют, но не могу сказать, чтобы я в целом в чём-то отставал, хотя теперь стало понятно, что в своем стеке надо подтянуть: работу с кастомной моделью пользователя и токенами аутентификации.
В самом начале определился лид команды - самый активный участник группы.
Сейчас, пока продакты исследуют рынок, а проджекты с аналитиками готовят документацию, перед нами стоит задача развернуть проект в репозитории и сделать базовую регистрацию, авторизацию и сброс пароля.
Определились с задачами:
- Организовать "основу" проекта и правила работы в репозитории.
- Сделать авторизацию и регистрацию с использованием Django REST Framework и JSON Web Token.
- Реализовать сброс пароля зарегистрированного пользователя.
Первую задачу взял на себя наш лид. После того, как он всё сделает, а мы это изучим, созвонимся снова и распределим оставшиеся задачи.
На удивление, мне есть, что предложить проекту, а именно у меня есть небольшой опыт работы с JWT аутентификацией между Django и Vue. Конечно, тут всё серьёзнее, чем на моём lkeep.ru, но, тем не менее, я не "хлопаю глазами" и не задаюсь вопросом "а как?".
В общем, наконец-то началось "движение". Очень интересно, в каком направлении пойдёт проект после исследования, какие задачи придётся выполнять и как будет выглядеть процесс взаимодействия с командой.
Пост на сайте
Поддержать проект
#Django #Стажировка #LAD_Academy #Backend #Код_на_салфетке #Frontend #Project #Product #Analytic #Vue
Потом была пара общих собраний, на которых в основном обсуждалась концепция проекта. Я на этих звонках сидел "ниже воды, тише травы", поскольку всё это для меня в новинку и, по правде говоря, мало что понимал в обсуждениях. Сидел, слушал, пытался уяснить и набирался опыта.
Объяснили, как работать в Mattermost и как будут распределяться задачи на SCRUM-доске. Придётся привыкать к нему, так как, не считая Telegram-чатов для "быстрого" реагирования, это должно стать основным место для обсуждений.
Продакты провели анализ конкурентов и предоставили варианты направления развития проекта.
Сейчас они продолжают исследования, для этого запустили опрос среди тех кто покупал курсы по обучению программированию себе или детям. Если есть желание помочь в исследовании, можете заполнить анкету по ссылке: https://docs.google.com/forms/d/e/1FAIpQLScmkxKpesSroNG0GYxuUS8ruOIjObQ1otITffpBoBPhFQvXBw/viewform
С бэками созванивались два раза.
Первый созвон был для знакомства с командой. На нём нужно было рассказать о себе. Я, конечно, волновался, потому что не очень понимал, что рассказать о себе. Но, послушав остальных, сумел кое-как рассказать о своем опыте и навыках. Команда подобралась разношерстная.
Второй созвон оказался интереснее и был посвящён обсуждению начала работы над проектом. Знания некоторых коллег впечатляют, но не могу сказать, чтобы я в целом в чём-то отставал, хотя теперь стало понятно, что в своем стеке надо подтянуть: работу с кастомной моделью пользователя и токенами аутентификации.
В самом начале определился лид команды - самый активный участник группы.
Сейчас, пока продакты исследуют рынок, а проджекты с аналитиками готовят документацию, перед нами стоит задача развернуть проект в репозитории и сделать базовую регистрацию, авторизацию и сброс пароля.
Определились с задачами:
- Организовать "основу" проекта и правила работы в репозитории.
- Сделать авторизацию и регистрацию с использованием Django REST Framework и JSON Web Token.
- Реализовать сброс пароля зарегистрированного пользователя.
Первую задачу взял на себя наш лид. После того, как он всё сделает, а мы это изучим, созвонимся снова и распределим оставшиеся задачи.
На удивление, мне есть, что предложить проекту, а именно у меня есть небольшой опыт работы с JWT аутентификацией между Django и Vue. Конечно, тут всё серьёзнее, чем на моём lkeep.ru, но, тем не менее, я не "хлопаю глазами" и не задаюсь вопросом "а как?".
В общем, наконец-то началось "движение". Очень интересно, в каком направлении пойдёт проект после исследования, какие задачи придётся выполнять и как будет выглядеть процесс взаимодействия с командой.
Пост на сайте
Поддержать проект
#Django #Стажировка #LAD_Academy #Backend #Код_на_салфетке #Frontend #Project #Product #Analytic #Vue
🔥8
Что выведет код выше?
Anonymous Quiz
13%
Всего 5 конфет.
44%
Всего 6 конфет.
16%
UnboundLocalError
28%
Ничего из перечисленного выше.
🔥1
Вчера мы опубликовали первую задачу из рубрики «Полезное из мешка». Задача скорее требовала внимательности, а не специальных знаний.
Общее количество ответов на данный момент 43, из них верных 11, а если вычесть 4-х человек, которые точно знали ответ на задачу, то правильных остаётся всего 7 ответов. Это даже меньше, чем если бы каждый отвечавший выбирал ответ случайным образом :(
Код из задачи:
Объяснение задачи:
В переменную
Функция
Функция
Хитрость в том, что функция
либо в этой:
Как вам новая рубрика? Стоит продолжать?
#что_выведет_данный_код #задачи_на_салфетке #python #функции #полезное_из_мешка
Общее количество ответов на данный момент 43, из них верных 11, а если вычесть 4-х человек, которые точно знали ответ на задачу, то правильных остаётся всего 7 ответов. Это даже меньше, чем если бы каждый отвечавший выбирал ответ случайным образом :(
Код из задачи:
def get_candy():
candy = 5
def increment_candy():
nonlocal candy
candy += 1
return candy
return increment_candy
result = get_candy()
print('Всего {} конфет.'.format(result))
Объяснение задачи:
В переменную
result мы помещаем результат вызова функции get_candy.Функция
get_candy: в ней мы объявляем переменную candy и записываем в неё пять конфет. Далее в ней же создается внутренняя функция increment_candy.Функция
increment_candy: в ней мы объявляем переменную candy нелокальной: то есть работая с этой переменной далее, мы будем обращаться к переменной из внешней функции get_candy - той самой, куда мы записали 5 конфет. Далее мы увеличиваем число конфет в этой переменной на единицу и возвращаем ее значение 6.Хитрость в том, что функция
get_candy (внешняя) не возвращает результат работы функции increment_candy (внутренней). Она лишь возвращает саму эту внутреннюю функцию, не вызывая ее. Чтобы вернуть именно результат ее работы, нужно вызвать эту внутреннюю фунцию, добавив скобки либо в этой строке:return increment_candy()
либо в этой:
result = get_candy()()
Как вам новая рубрика? Стоит продолжать?
#что_выведет_данный_код #задачи_на_салфетке #python #функции #полезное_из_мешка
🔥12
Статистика сайта за месяц 03.11-04.12
Автор: Иван Ашихмин
Прошёл ещё месяц и пора изучать статистику.
Растёт доля переходов из поиска. Основными поисковыми запросами по-прежнему являются AIOgram и FreeGPT, а в этом месяце к ним присоединились ещё и запросы про Docker (в основном MailServer) и стажировку в Aston. Удивительно, что на сайте столько постов про Django, а его в запросах почти нет.
Переходы из Telegram, Dzen и прямые заходы практически сравнялись.
В целом меня радует рост поисковой выдачи, но над SEO ещё работать и работать.
К слову, если кто-то из вас разбирается в SEO-оптимизации и сможет подсказать по основным моментам, как и что, буду благодарен 🙂.
В сухом итоге:
- Посетители: Было 500, стало 785. Прирост 57%.
- Переходы из Dzen: Было 12.6%, стало 13.1%. Прирост 3.96%.
- Переходы из Telegram-канала: Было 18%, стало 11.6%. Падение 35.55%.
- Переходы из поиска: Было 48.1%, стало 58.3%. Прирост 21.20%.
Автор: Иван Ашихмин
Прошёл ещё месяц и пора изучать статистику.
Растёт доля переходов из поиска. Основными поисковыми запросами по-прежнему являются AIOgram и FreeGPT, а в этом месяце к ним присоединились ещё и запросы про Docker (в основном MailServer) и стажировку в Aston. Удивительно, что на сайте столько постов про Django, а его в запросах почти нет.
Переходы из Telegram, Dzen и прямые заходы практически сравнялись.
В целом меня радует рост поисковой выдачи, но над SEO ещё работать и работать.
К слову, если кто-то из вас разбирается в SEO-оптимизации и сможет подсказать по основным моментам, как и что, буду благодарен 🙂.
В сухом итоге:
- Посетители: Было 500, стало 785. Прирост 57%.
- Переходы из Dzen: Было 12.6%, стало 13.1%. Прирост 3.96%.
- Переходы из Telegram-канала: Было 18%, стало 11.6%. Падение 35.55%.
- Переходы из поиска: Было 48.1%, стало 58.3%. Прирост 21.20%.