Top.Mail.Ru

Новостной сайт на Django и упаковка в Docker на сайте dockerhosting.ru

Новостной сайт на Django и упаковка в Docker на сайте dockerhosting.ru

Новостной сайт на 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 делает процесс деплоя максимально простым и быстрым — без необходимости самостоятельно настраивать сервер. Попробуйте сами: создайте свой новостной сайт, упакуйте его в контейнер и запустите за считанные минуты!

Автор:

66

Читайте также

0 комментариев

Бот: Здравствуйте! Я чат-бот веб-разработчика. Чем могу помочь в создании или доработке вашего сайта?