October 21

Django

Проект создается с помощью команды

django-admin startproject название_проект

  • в результате чего создаётся файл manage.py и папка с тем же именем
  • по manage.py можно идентефицировать проект
  • в одноимённом папке есть настройки Django
mysite/
│
├── manage.py   <====
│
└── mysite/     <==== Одноимённая папка с конфигурацией
    ├── __init__.py ├── asgi.py
    ├── settings.py ├── urls.py └── wsgi.py

Приложение это просто логически отделённые части, например, для опросов или регистрации. Они помогают удобно разделять логику, что бы не захламлять url.py название_проекта

  • Они имеют свои собственные url.py
  • В url.py ПРОЕКТА, можно подключать их(приложений) url.py через функцию include()

python manage.py startapp название

Полезная инфа:

https://cheatography.com/ogr/cheat-sheets/django/

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

  • path('testing', include('testing.urls')),

начинаеться с - 127.0.0.1:8000/testing/

  • 127.0.0.1:8000/testing | /name-page1 - задаётся в файле приложения
  • 127.0.0.1:8000/testing | /name-page2

#<username> будет унаследованна из родительских URLconfs
urlpatterns = [
    path("<username>/blog/", include("foo.urls.blog")),
]
path('testing', include('women.urls'))

Однако если эту строчку оставить пустой, то такого эффекта не будет

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('testing.urls')),
]

Функции во views.py

https://docs.djangoproject.com/en/5.1/topics/http/urls/

  • str – любая не пустая строка, исключая символ ‘/’;
  • int – любое положительное целое число, включая 0;
  • slug – слаг, то есть, латиница ASCII таблицы, символы дефиса и подчеркивания;
  • uuid – цифры, малые латинские символы ASCII, дефис;
  • path – любая не пустая строка, включая символ ‘/’.
# str – непустая строка, исключая '/'
path('items/<str:item_name>/', views.item_detail)
# int – положительное целое число, включая 0
path('products/<int:product_id>/', views.product_detail)
# slug – латиница ASCII, дефисы и подчеркивания
path('articles/<slug:article_slug>/', views.article_detail)
# uuid – цифры, малые латинские символы и дефис
path('users/<uuid:user_id>/', views.user_detail)
# path – непустая строка, включая '/'
path('files/<path:file_path>/', views.file_detail)

Более детальное понимание наступит столкнувшись с ними в базах данных

Контекст:

Django имеет свой ЯЗЫК ШАБЛОНОВ (Django template language)

<ul>
{% for x in fruits %}
  <li style='color:{% cycle 'red' 'green' 'blue' 'pink' %}'>
    {{ x }}
  </li>
{% endfor %}
</ul>

Это обычный цикл, пока что посмотрим на суть:

    return render(request, 'index.html', context)
    
# обычный словарь что нужно передать в параметры функции 
    context = {
    'fruits': ['Apple', 'Banana', 'Cherry', 'Orange']
    }

  • context — словарь, содержащий ключ fruits с листом фруктов:
  • {% for x in fruits %} — стандартный цикл для перебора элементов fruits
  • {{ x }} — выводит текущий элемент в каждой итерации.

т.е основные приколы тут в точечной нотации:

<ul>
    <li>{{ fruits.0 }}</li>  <!-- Первый элемент списка  индекс [0] -->
    <li>{{ fruits.1 }}</li>  <!-- Второй элемент списка  индекс [1] -->
</ul>

так же с атрибутами , ключами, и другими типами коллекций

Оператор управления if, for итд:

{% Control flow statements %}

Обязательно закрывать:

{% endfor %}


{{ скобки }} Они нужны для отображения типа данных (ключей - переменных с их содеражанием, в данном случае мы получаем их из объектов, по точечной нотации:

Name: {{ user.name }}
Age: {{ user.age }}
Email: {{ user.email }}

Правило: одна фигурная скобка, на один ключ:

<p>{{ dict.key_1 }} {{ dict.key_2 }}</p> # {{ключ}} {{ключ}} 

Все фильтры в Django шаблонах используют один и тот же синтаксис:


{{ variable | filter_name: arg1:arg2 }}

https://docs.djangoproject.com/en/5.1/ref/templates/builtins/#built-in-filter-reference

```python
    <h2>Тег filter</h2>
    <p>Отфильтрованный текст: {{ "Пример текста"|filter:"upper" }}</p>
```

В папке проекта есть settings.py

Параметр `APP_DIRS: True` позволяет Django автоматически искать шаблоны в папках `templates` для всех установленных приложений.

Параметр `'DIRS': []` Содержит доп. пути к директориям, где Django будет искать шаблоны
```python
'DIRS': ['templates\mem'] 
#=========
return render(request, 'lol\index.html', context = date)
# lol\index.htmll - было бы как:
'DIRS': ['templates\mem\lol']
```

Список всех приложений settings.py в переменной INSTALLED_APPS:
INSTALLED_APPS = [          # contrib директория модулей
    'django.contrib.admin', # Админка сайта. 
    'django.contrib.auth',  # Система аутентификации.
    'django.contrib.contenttypes', # модуль для типов контента.
    'django.contrib.sessions', # модуль сеанса.
    'django.contrib.messages', # модуль для обмена сообщениями.
    'django.contrib.staticfiles', # модуль для управления статическими файл
	
	#добавлять свои приложения так так:
    'example.apps.ExampleConfig',
]

разные импорты для URLs:

from django.urls import path, re_path, include, reverse

Именование URL-маршрутов, не путать contact/

```
path('contact/', views.contact,
	 name='contactiki'), #имя маршрута для нашего удобства
```

https://www.geeksforgeeks.org/url-django-template-tag/

```python
<a href="{% url 'contact' %}">Контакты</a> к имени маршрута
# оно станет ссылкой
```

или так

def my_view(request):
    url = reverse('my-url-name')
    return HttpResponseRedirect(url)

r'^articles/([0-9]{4})/#39; — это регулярное выражение, которое соответствует URL, содержащим год (например, articles/2023/).

Общие маршруты с меньшей вложенностью должны определяться в последнюю очередь, а более специфичные и глубокие маршруты — первыми. По этому стоит учитывать отборажение Patch Converter-ов

Шаблоны:

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

Контент разметки одного HTML файла как бы всовывается в другой.

- `{% block %}`: используется для обозначения областей в родительском шаблоне, которые могут быть изменены или переопределены в дочерних шаблонах. Завершается она конструкцией {% endblock %}.

- `{% extends %}`: Эта что текущий шаблон является дочерним по отношению к другому (родительскому) шаблону. Например, {% extends "base.html" %} обозначает, что текущий шаблон наследует структуру из файла base.html.

Базовый, родительский шаблон это вся структура которая нужно унаследовать для всех шаблонов: заголовки, навигация итд, реализация принципа DRY

Тег include просто тупо вставляет всё содержимое целиком:


{% include 'header.html' %}

МОДЕЛИ и CRUD:

В Django для выбора записей из таблиц используются методы менеджера `QuerySet`, такие как `filter()`, `exclude()`, `get()`, `all()` и другие.

Эти методы позволяют выполнять запросы к базе данных и извлекать данные в соответствии с заданными условиями.


get(): возвращает одну запись, соответствующую заданным условиям. Если запись не найдена или найдено более одной, будет вызвано исключение.

   ```python
   record = MyModel.objects.get(pk=1)
   ```

- DoesNotExist: не найдено ни одного объекта, соответствующего заданным условиям.
- MultipleObjectsReturned: найдено более одного объекта, соответствующего заданным условиям.

### Примеры использования:
```python
# Извлечение объекта по первичному ключу:
obj = MyModel.objects.get(pk=1)
# Извлечение объекта по уникальному полю:
obj = MyModel.objects.get(unique_field='unique_value')
# Извлечение объекта по нескольким полям:
obj = MyModel.objects.get(field1='value1', field2='value2')
```

all() список всех QuerySet объектов из БД

1. Извлечение всех объектов модели:

```python
all_objects = MyModel.objects.all()
for obj in all_objects:
    print(obj)
```

2. Подсчет количества объектов

```python
count = MyModel.objects.all().count()
print(f"Количество объектов: {count}")
```

3. Это возвращает объекты с 6 по 10 (OFFSET 5 : LIMIT 5)

``python
>>> Entry.objects.all()[5:10]
#Negative indexing (i.e. Entry.objects.all()[-1]) is not supported.
``

filter(): возвращает записи, которые соответствуют заданным условиям.

exclude(): возвращает записи, которые не соответствуют заданным условиям поискаj, отрицательная фильтрация.


https://www.w3schools.com/django/django_ref_field_lookups.php

Field lookups — это специальные фильтры, которые позволяют выполнять более сложные запросы.

  • Каждый атрибут модели представляет собой поле базы данных.
  • Каждая модель представляет собой класс Python, являющийся подклассом django.db.models.Model.
  • Класс модели представляет таблицу базы данных, а экземпляр этого класса представляет конкретную запись в таблице базы данных.

https://www.w3schools.com/django/django_ref_field_lookups.php

Many-To-One

модель, на которую ссылается внешний ключ

* `on_delete`: обязательный параметр, который определяет поведение при удалении связанного объекта. Возможные значения:

```python
models.CASCADE:# при удалении связанного объекта, все объекты, ссылающиеся на него, также будут удалены.
#
models.PROTECT:# предотвращает удаление связанного объекта, если на него ссылаются другие объекты.
#
models.SET_NULL:# устанавливает значение поля в NULL, если связанный объект был удален (требует, чтобы поле было null=True).
#
models.SET_DEFAULT:# устанавливает значение поля в значение по умолчанию, если связанный объект был удален.
#
models.RESTRICT:# предотвращает удаление связанного объекта, если на него ссылаются другие объекты, но не вызывает исключение.
#
models.DO_NOTHING:# не выполняет никаких действий при удалении связанного объекта (может вызвать ошибки целостности данных).

cheese_blog = Blog.objects.get(name="Cheddar Talk")    # <========= |
#Получается объект `Blog` с именем "Cheddar Talk".                  \
entry.blog = cheese_blog                               # <===========
# Полю `blog` объекта `entry` присваивается объект `cheese_blog`.

ManyToManyField

Миграции

`PRIMARY KEY`- первичный ключ, он же id, он же .pk
`(foreign key) -` связывает две разные таблицы между собой


* null
* blank
* coices

create() используется для создания и сохранения нового объекта модели в базе данных.
``python
mm = MyModelClass.objects.create(field1=value1, field2=value2, ...)
mm.pk
``