Создание Django проекта для новичка
django-admin startproject myproject
cd myproject
python manage.py startapp myapp
Добавление приложения в INSTALLED_APPS:
INSTALLED_APPS = [
...
'myapp',
]
Создание моделей в myapp/models.py:
class MyModel(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
Создание и применение миграций:
python manage.py makemigrations
python manage.py migrate
Включаем админ панель admin.py должен выглядеть так:
from django.contrib import admin
from .models import Post // Импортируем нашу модель
Теперь у нас есть Django проект myproject в котором есть приложение myapp. По мимо этого у нас есть модель данных Post которая имеет два поля и мы провели ее миграции. Это значит мы можем по готовому шаблону помещать данные в базу данных которая уже есть в проекте. В конце мы подключили эту базу данных в админ панель, и теперь можем делать записи.
Часть 2 - Представления
Теперь нам надо на какой то странице выводить данные из нашей модели. Допустим у нас будет главная страница, и на ней мы отобразим наши записи.
Создание представления (View)
Откройте файл myapp/views.py и добавьте следующий код:
from django.shortcuts import render
from .models import MyModel
def post_list(request):
posts = MyModel.objects.all() # Получаем все записи из модели MyModel
return render(request, 'myapp/post_list.html', {'posts': posts})
Тут мы получили все записи нашей модели, и возвращаем страницу post_list.html с данными posts которые несут в себе все записи. (Далее мы ее создадим)
Маршруты urls
Откройте или создайте файл myapp/urls.py и добавьте следующий код:
from django.urls import path
from . import views
urlpatterns = [
path('', views.post_list, name='post_list'),
]
Тут мы говорим что если пользователь перейдет на страницу '', что по умолчанию главная, то сработает представление views.post_list. Можно сделать path('all_posts', views.post_list, name='post_list') // Тогда загружаться все будет не с site.ru, а с site.ru/all_posts
Откройте файл myproject/urls.py и импортируйте include:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('myapp.urls')), # Подключаем маршруты приложения myapp
]
С начала мы приложению сказали что открывать, теперь мы проекту скажем что если будет переход на '', - главную, мы обращаемся к urls приложения. А там мы уже написали какое представление запускать.
Создание шаблона
myapp/
templates/
myapp/
post_list.html
Создайте папку как показано выше и в ней еще одну папку. Важно смотрите за названиями, название папки - название приложения в котором ее создали. Templates всегда одно и то же, как в примере.
В настройках прописать путь как в примере:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'], # Убедитесь, что путь указан правильно
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
В файле post_list.html добавьте следующий код:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Посты</title>
</head>
<body>
<h1>Список постов</h1>
<ul>
{% for post in posts %}
<li>
<strong>{{ post.name }}</strong><br>
{{ post.description }}
</li>
{% endfor %}
</ul>
</body>
</html>
Самое простое обращение к данным модели - это просто обратиться к ней через цикл так как в представлении мы передавали массив со всеми записями.
В общем этот гайд подсказка для меня самого. Буду дополнять
Часть 3 - бесконечность
При выводе текста, используй фильтр который сохранит в тесте абзацы заменив пустоту на <br>. Используй: {{ post.description|linebreaks }}
{{ post.content|linebreaks|truncatewords:"20" }}Например тут мы с начала делаем абзацы, далее сокращаем до 20 слов текст.
ВАЖНО! СОЗДАЕМ ДЕТАЛЬНУЮ СТРАНИЦУ ЗАПИСИ С ПОЛНЫМ ЕЕ ТЕКСТОМ
Чтобы сделать так, чтобы пользователи могли перейти к полной записи и прочитать её полный текст, необходимо выполнить несколько шагов:
- Создать представление для отображения деталей записи.
- Создать URL для этого представления.
- Обновить шаблон для добавления ссылок на детали записи.
Откройте файл myapp/views.py и добавьте представление для отображения деталей записи:
from django.shortcuts import render, get_object_or_404
from .models import MyModel
def post_list(request):
posts = MyModel.objects.all()
return render(request, 'myapp/post_list.html', {'posts': posts})
def post_detail(request, pk):
post = get_object_or_404(MyModel, pk=pk)
return render(request, 'myapp/post_detail.html', {'post': post})
Тут get_object_or_404 получает данные модели Post только не всех записей а еще с pk=pk ее типа id.
Создание URL для представления деталей записи
Откройте файл myapp/urls.py и добавьте URL для нового представления:
from django.urls import path
from . import views
urlpatterns = [
path('', views.post_list, name='post_list'),
path('post/<int:pk>/', views.post_detail, name='post_detail'), # Добавляем URL для деталей записи
]
Тут говорим что если сработает страница /post/и любое число то сработает представление в котором мы получим запись с pk= числу. Например site.ru/post/4 - будет искать 4-ую запись в модели post
Создайте новый файл myapp/templates/myapp/post_detail.html и добавьте в него следующий код:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ post.name }}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 20px;
}
h1 {
color: #333;
}
.post-detail {
max-width: 800px;
margin: 0 auto;
}
.post-header {
margin-bottom: 20px;
}
.post-content {
margin-bottom: 20px;
}
.back-link {
display: inline-block;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="post-detail">
<div class="post-header">
<h1>{{ post.name }}</h1>
<small class="text-muted">{{ post.date_posted }}</small>
</div>
<div class="post-content">
<p>{{ post.description|linebreaks }}</p>
</div>
<div class="back-link">
<a href="{% url 'post_list' %}" class="btn btn-secondary">Назад к списку постов</a>
</div>
</div>
</body>
</html>
Вот простой пример как можно вывести полные данные в шаблон post_detail.html
Получаем все записи из модели Post от новых к старым
posts = Post.objects.all().order_by('-date_posted') ДЕЛАЕМ РЕЙТИНГ У ЗАПИСЕЙ
rating = models.IntegerField(default=0)
Далее добавим в файл views новые представления
def upvote(request, pk):
obj = get_object_or_404(MyModel, pk=pk)
obj.rating += 1
obj.save()
return redirect('post_detail', pk=pk)
def downvote(request, pk):
obj = get_object_or_404(MyModel, pk=pk)
obj.rating -= 1
obj.save()
return redirect('post_detail', pk=pk)
Наш urls приложения теперь такой:
from django.urls import path
from . import views
urlpatterns = [
path('', views.post_list, name='post_list'),
path('post/<int:pk>/', views.post_detail, name='post_detail'),
path('post/<int:pk>/upvote/', views.upvote, name='upvote'),
path('post/<int:pk>/downvote/', views.downvote, name='downvote'),
Теперь мы можем в шаблоне вызвать
<b>Рейтинг: {{ post.rating }}</b>А в файл с деталями записи можно вставить:
<p><b>Рейтинг: {{ post.rating }}</b></p>
<br>
<!-- Отдельные ссылки для голосования -->
<a href="{% url 'upvote' post.pk %}" class="btn btn-success me-2 btn-sm">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-hand-thumbs-up" viewBox="0 0 16 16">
<path d="err"/>
</svg>
Нравиться
</a>
<a href="{% url 'downvote' post.pk %}" class="btn btn-danger btn-sm">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-hand-thumbs-down" viewBox="0 0 16 16">
<path d="err"/>
</svg>
Не нравиться
</a>