1. Структура проекта
todo_django_app/ # Корень пакета
├── todo_app/ # Основной пакет
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations/
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── setup.py # Для установки через pip
├── README.md
├── LICENSE
├── MANIFEST.in # Включает дополнительные файлы
└── requirements.txt
2. Основные файлы
todo_app/models.py
from django.db import models
from django.contrib.auth.models import User
class Todo(models.Model):
"""Модель задачи"""
title = models.CharField(max_length=200, verbose_name="Заголовок")
description = models.TextField(blank=True, verbose_name="Описание")
completed = models.BooleanField(default=False, verbose_name="Выполнено")
created_at = models.DateTimeField(auto_now_add=True, verbose_name="Создано")
updated_at = models.DateTimeField(auto_now=True, verbose_name="Обновлено")
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='todos',
verbose_name="Пользователь"
)
class Meta:
verbose_name = "Задача"
verbose_name_plural = "Задачи"
ordering = ['-created_at']
def __str__(self):
return self.title
todo_app/admin.py
from django.contrib import admin
from .models import Todo
@admin.register(Todo)
class TodoAdmin(admin.ModelAdmin):
list_display = ('title', 'user', 'completed', 'created_at')
list_filter = ('completed', 'created_at')
search_fields = ('title', 'description')
date_hierarchy = 'created_at'
readonly_fields = ('created_at', 'updated_at')
todo_app/views.py
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .models import Todo
@login_required
def todo_list(request):
"""Список задач пользователя"""
todos = Todo.objects.filter(user=request.user)
return render(request, 'todo_app/todo_list.html', {'todos': todos})
@login_required
def todo_detail(request, pk):
"""Детали задачи"""
todo = get_object_or_404(Todo, pk=pk, user=request.user)
return render(request, 'todo_app/todo_detail.html', {'todo': todo})
@login_required
def todo_create(request):
"""Создание новой задачи"""
if request.method == 'POST':
title = request.POST.get('title')
description = request.POST.get('description', '')
if title:
Todo.objects.create(
title=title,
description=description,
user=request.user
)
messages.success(request, 'Задача создана!')
return redirect('todo_app:list')
return render(request, 'todo_app/todo_form.html')
@login_required
def todo_update(request, pk):
"""Обновление задачи"""
todo = get_object_or_404(Todo, pk=pk, user=request.user)
if request.method == 'POST':
todo.title = request.POST.get('title', todo.title)
todo.description = request.POST.get('description', todo.description)
todo.completed = 'completed' in request.POST
todo.save()
messages.success(request, 'Задача обновлена!')
return redirect('todo_app:list')
return render(request, 'todo_app/todo_form.html', {'todo': todo})
@login_required
def todo_delete(request, pk):
"""Удаление задачи"""
todo = get_object_or_404(Todo, pk=pk, user=request.user)
if request.method == 'POST':
todo.delete()
messages.success(request, 'Задача удалена!')
return redirect('todo_app:list')
return render(request, 'todo_app/todo_confirm_delete.html', {'todo': todo})
todo_app/urls.py
from django.urls import path
from . import views
app_name = 'todo_app'
urlpatterns = [
path('', views.todo_list, name='list'),
path('create/', views.todo_create, name='create'),
path('<int:pk>/', views.todo_detail, name='detail'),
path('<int:pk>/update/', views.todo_update, name='update'),
path('<int:pk>/delete/', views.todo_delete, name='delete'),
]
todo_app/apps.py
from django.apps import AppConfig
class TodoAppConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'todo_app'
verbose_name = "Менеджер задач"
3. Шаблоны (необязательно, но полезно)
Создадим директорию templates/todo_app/ внутри приложения:
todo_app/
├── templates/
│ └── todo_app/
│ ├── todo_list.html
│ ├── todo_detail.html
│ ├── todo_form.html
│ └── todo_confirm_delete.html
todo_app/templates/todo_app/todo_list.html (пример):
<!DOCTYPE html>
<html>
<head>
<title>Мои задачи</title>
</head>
<body>
<h1>Мои задачи</h1>
<a href="{% url 'todo_app:create' %}">Создать задачу</a>
<ul>
{% for todo in todos %}
<li>
<input type="checkbox" {% if todo.completed %}checked{% endif %} disabled>
<a href="{% url 'todo_app:detail' todo.pk %}">{{ todo.title }}</a>
<small>{{ todo.created_at|date:"d.m.Y H:i" }}</small>
<a href="{% url 'todo_app:update' todo.pk %}">✏️</a>
<a href="{% url 'todo_app:delete' todo.pk %}">🗑️</a>
</li>
{% empty %}
<li>Нет задач. <a href="{% url 'todo_app:create' %}">Создать первую?</a></li>
{% endfor %}
</ul>
</body>
</html>
4. setup.py - самый важный файл для установки
from setuptools import setup, find_packages
import os
# Чтение README
with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()
# Чтение требований
with open("requirements.txt", "r", encoding="utf-8") as fh:
requirements = fh.read().splitlines()
setup(
name="django-todo-app", # Имя пакета на PyPI
version="0.1.0", # Версия
author="Ваше Имя",
author_email="your.email@example.com",
description="Простое Django приложение для управления задачами",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/yourusername/django-todo-app",
# Находим все пакеты
packages=find_packages(),
# Указываем, что это Django приложение
include_package_data=True,
# Классификаторы для PyPI
classifiers=[
"Development Status :: 4 - Beta",
"Environment :: Web Environment",
"Framework :: Django",
"Framework :: Django :: 3.2",
"Framework :: Django :: 4.0",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
],
# Зависимости
install_requires=requirements,
# Дополнительные зависимости для разработки
extras_require={
"dev": [
"pytest>=6.0",
"pytest-django",
"black",
"flake8",
],
},
# Python версия
python_requires=">=3.8",
# Ключевые слова для поиска
keywords="django, todo, tasks, productivity",
# Проект поддерживает установку через pip
zip_safe=False,
# Чтобы можно было импортировать как django-todo-app
entry_points={
'console_scripts': [],
},
)
5. MANIFEST.in - для включения дополнительных файлов
include LICENSE
include README.md
include requirements.txt
recursive-include todo_app/templates *
recursive-include todo_app/static *
recursive-include todo_app/locale *
6. requirements.txt
Django>=3.2,<5.0
7. README.md
# Django Todo App
Простое Django приложение для управления задачами.
## Установка
```bash
pip install django-todo-app
Настройка
- Добавьте
'todo_app'вINSTALLED_APPS:
# settings.py
INSTALLED_APPS = [
...,
'todo_app',
]
- Выполните миграции:
python manage.py migrate
- Добавьте URL в ваш проект:
# urls.py проекта
from django.urls import path, include
urlpatterns = [
...,
path('todos/', include('todo_app.urls', namespace='todo_app')),
]
- Создайте суперпользователя для доступа к админке:
python manage.py createsuperuser
Использование
После установки перейдите по адресу /todos/ для работы с задачами.
Лицензия
MIT
## **8. `LICENSE`** (MIT лицензия)
```text
MIT License
Copyright (c) 2024 Ваше Имя
Permission is hereby granted...
9. Как использовать/тестировать локально
Установка в режиме разработки:
# В директории todo_django_app/
pip install -e .
Создание дистрибутива:
python setup.py sdist bdist_wheel
Загрузка на PyPI (TestPyPI для тестирования):
# Установите twine если нет
pip install twine
# Загрузите на TestPyPI
twine upload --repository testpypi dist/*
# Загрузите на PyPI
twine upload dist/*
10. Как другой разработчик установит ваш пакет
# Из PyPI
pip install django-todo-app
# Или напрямую из GitHub
pip install git+https://github.com/yourusername/django-todo-app.git
# Или определенную версию
pip install django-todo-app==0.1.0
11. Пример использования в другом Django проекте
# settings.py другого проекта
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Установленный пакет
'todo_app',
]
# urls.py
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('todos/', include('todo_app.urls', namespace='todo_app')),
path('accounts/', include('django.contrib.auth.urls')),
]
12. Добавим фикстуры для тестовых данных
todo_app/fixtures/initial_data.json (опционально):
[
{
"model": "todo_app.todo",
"pk": 1,
"fields": {
"title": "Пример задачи",
"description": "Это пример задачи",
"completed": false,
"created_at": "2024-01-01T10:00:00Z",
"updated_at": "2024-01-01T10:00:00Z",
"user": 1
}
}
]
13. Добавим тесты
todo_app/tests.py:
from django.test import TestCase
from django.contrib.auth.models import User
from django.urls import reverse
from .models import Todo
class TodoModelTest(TestCase):
def setUp(self):
self.user = User.objects.create_user(
username='testuser',
password='testpass123'
)
self.todo = Todo.objects.create(
title='Test Todo',
description='Test Description',
user=self.user
)
def test_todo_creation(self):
self.assertEqual(self.todo.title, 'Test Todo')
self.assertEqual(self.todo.user.username, 'testuser')
self.assertFalse(self.todo.completed)
def test_todo_str(self):
self.assertEqual(str(self.todo), 'Test Todo')
class TodoViewTest(TestCase):
def setUp(self):
self.user = User.objects.create_user(
username='testuser',
password='testpass123'
)
self.client.login(username='testuser', password='testpass123')
def test_todo_list_view(self):
response = self.client.get(reverse('todo_app:list'))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'todo_app/todo_list.html')
Итог:
setup.py— главный файл для установки через pip__init__.py— делает директорию Python пакетом- Стандартная структура Django app — models, views, urls, admin
MANIFEST.in— включает дополнительные файлы (шаблоны, статику)- Документация — README.md, LICENSE
Чтобы установить ваш модуль:
# Локальная разработка
pip install -e /path/to/todo_django_app
# Из архива
pip install todo_django_app-0.1.0.tar.gz
# Из PyPI
pip install django-todo-app
Такой модуль можно:
- Установить в любой Django проект
- Распространять через PyPI
- Использовать как зависимость в других проектах
- Версионировать и обновлять
Оставить отзыв
Комментарии
Загрузка комментариев...
★ Оставить отзыв