Новостной сайт на Django и упаковка в Docker: простой путь к деплойменту на dockerhosting.ru
Создание новостного сайта с использованием Django — мощного фреймворка Python — отличный способ организовать информационный ресурс с возможностью управления контентом, авторизацией пользователей и масштабируемостью. Для того, чтобы проект стал востребованным в интернете, его необходимо правильно «развернуть». Один из самых современных способов — упаковка приложения в Docker-контейнер и размещение на dockerhosting.ru.
Почему Django?
Django — это фреймворк, который позволяет быстро разрабатывать безопасные и масштабируемые веб-приложения. Его основные преимущества:
- Встроенная админ-панель для управления статьями;
- Поддержка авторизации, сессий, форм и шаблонов;
- ORM (объектно-реляционное отображение) для работы с базами данных;
- Большое сообщество и множество готовых решений.
Небольшой проект, на примере которого мы продемонстрируем простой путь к деплойменту с помощью Django, включает в себя:
- различные категории новостей;
- регистрацию и авторизацию пользователей;
- возможность публикации новостей авторизованными пользователями;
- разделением прав упрощённым фронтендом на Django templates (то есть, только автор может редактировать/удалять свои статьи).
Также проект содержит следующие структурные элементы:
- users – приложение для регистрации/логина.
- news – основное приложение с моделями Category, Article.
- templates/ – шаблоны сайта.
- static/ – CSS, JS, картинки (если нужно).
Установка и настройка новостного сайта на Django
django-admin startproject newsportal
cd newsportal
python manage.py startapp news
python manage.py startapp users
В settings.py
:
INSTALLED_APPS = [
...
'news',
'users',
'django.contrib.sites', # для allauth, если используете
]
LOGIN_URL = 'login'
LOGIN_REDIRECT_URL = 'article_list'
LOGOUT_REDIRECT_URL = 'login'
Модель категорий и новостей (news/models.py
)
from django.db import models
from django.contrib.auth.models import User
class Category(models.Model):
name = models.CharField(max_length=100, unique=True)
def __str__(self):
return self.name
class Article(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=255)
content = models.TextField()
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
Формы (news/forms.py
)
from django import forms
from .models import Article
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ['title', 'content', 'category']
Представления (news/views.py
)
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from .models import Article, Category
from .forms import ArticleForm
def article_list(request):
articles = Article.objects.select_related('author', 'category').order_by('-created_at')
return render(request, 'news/article_list.html', {'articles': articles})
def article_detail(request, pk):
article = get_object_or_404(Article, pk=pk)
return render(request, 'news/article_detail.html', {'article': article})
@login_required
def article_create(request):
if request.method == 'POST':
form = ArticleForm(request.POST)
if form.is_valid():
article = form.save(commit=False)
article.author = request.user
article.save()
return redirect('article_list')
else:
form = ArticleForm()
return render(request, 'news/article_form.html', {'form': form})
Регистрация и авторизация (users/views.py
)
from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import render, redirect
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect('login')
else:
form = UserCreationForm()
return render(request, 'users/register.html', {'form': form})
Шаблоны
templates/base.html
<!DOCTYPE html>
<html>
<head>
<title>News Portal</title>
</head>
<body>
<nav>
{% if user.is_authenticated %}
<p>Hello, {{ user.username }} | <a href="{% url 'logout' %}">Logout</a></p>
<a href="{% url 'article_create' %}">New Article</a>
{% else %}
<a href="{% url 'login' %}">Login</a> |
<a href="{% url 'register' %}">Register</a>
{% endif %}
<a href="{% url 'article_list' %}">Home</a>
</nav>
<hr>
{% block content %}{% endblock %}
</body>
</html>
templates/news/article_list.html
{% extends 'base.html' %}
{% block content %}
<h2>Articles</h2>
{% for article in articles %}
<h3><a href="{% url 'article_detail' article.pk %}">{{ article.title }}</a></h3>
<p>By {{ article.author }} | {{ article.created_at }}</p>
{% empty %}
<p>No articles yet.</p>
{% endfor %}
{% endblock %}
URLs
news/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.article_list, name='article_list'),
path('article/<int:pk>/', views.article_detail, name='article_detail'),
path('article/new/', views.article_create, name='article_create'),
]
users/urls.py
from django.urls import path
from .views import register
urlpatterns = [
path('register/', register, name='register'),
]
newsportal/urls.py
from django.contrib import admin
from django.urls import path, include
from django.contrib.auth import views as auth_views
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('news.urls')),
path('', include('users.urls')),
path('login/', auth_views.LoginView.as_view(), name='login'),
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
]
После этого необходимо сделать миграцию и создать админа с помощью следующих команд:
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
Упаковка в docker
Далее работаем над укомплектацией проекта:
Dockerfile
FROM python:3.11-slim
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["gunicorn", "newsportal.wsgi:application", "--bind", "0.0.0.0:8000"]
Docker-файл (docker-compose.yml)
version: '3.9'
services:
web:
build: .
command: gunicorn mysite.wsgi:application --bind 0.0.0.0:8000
volumes:
- .:/app
ports:
- "8000:8000"
depends_on:
- db
db:
image: postgres:14
environment:
POSTGRES_DB: newsdb
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
Размещение на dockerhosting.ru
Платформа dockerhosting.ru — это удобный российский сервис для развёртывания Docker-приложений.
Основные шаги для деплоя:
1. Зарегистрируйтесь на dockerhosting.ru.
2. Создайте проект, выбрав Docker-контейнер.
3. Загрузите ваш Dockerfile и исходники через панель управления или Git.
4. Укажите команду запуска контейнера (gunicorn mysite.wsgi:application --bind 0.0.0.0:8000).
5. Пропишите переменные окружения (например, для БД).
6. Привяжите домен и включите HTTPS (при необходимости).
7. Запустите контейнер и наблюдайте, как ваш сайт «оживает».
Сочетание Django и Docker позволяет создавать гибкие и масштабируемые веб-приложения. А использование dockerhosting.ru делает процесс деплоя максимально простым и быстрым — без необходимости самостоятельно настраивать сервер. Попробуйте сами: создайте свой новостной сайт, упакуйте его в контейнер и запустите за считанные минуты!
Автор: Евгений Морковин
0 комментариев