Задание: расширение системы складского учёта
Вы уже создали 8 моделей и Admin-классы в практикуме 5. Теперь расширьте систему, добавив возможность оставлять отзывы о товарах.
Часть 1: Новая модель Review
Создайте модель Review в models.py с полями:
product— ForeignKey на модельProduct, PROTECT, related_name='reviews'customer— ForeignKey на модельCustomer, PROTECT, related_name='reviews'rating— целое число от 1 до 5 (используйтеPositiveSmallIntegerField; валидацию диапазона черезvalidators=[MinValueValidator(1), MaxValueValidator(5)])text— текст отзыва, необязательный (TextField(null=True, blank=True))created_at— дата и время, заполняется автоматически при создании
Добавьте:
- Метод
__str__, возвращающий строку:"Review by {customer} for {product}: {rating}/5" - Meta: сортировка по
created_atпо убыванию;unique_together = (('product', 'customer'),)— один клиент, один отзыв на товар
Часть 2: Admin для Review
Зарегистрируйте модель Review в Admin с классом ReviewAdmin:
- list_display:
product,customer,rating,created_at - search_fields: поиск по
product__name,customer__first_name,customer__last_name - list_filter:
rating,product - ordering: по
created_atпо убыванию
Часть 3: Миграции и проверка
- Создайте миграцию:
python manage.py makemigrations - Примените:
python manage.py migrate - Запустите сервер:
python manage.py runserver - Откройте
http://127.0.0.1:8000/admin/ - Создайте несколько отзывов через Admin
- Убедитесь, что нельзя создать два отзыва от одного клиента на один товар
Подготовка окружения
# В директории проекта
python -m venv venv
venv\Scripts\activate # Windows
pip install -r requirements.txt
# После изменения models.py
python manage.py makemigrations
python manage.py migrate
# Создать суперпользователя (если ещё нет)
python manage.py createsuperuser
python manage.py runserver
Пошаговое решение
Шаг 1: Модель Review в models.py
from django.core.validators import MinValueValidator, MaxValueValidator
class Review(models.Model):
product = models.ForeignKey(
Product, on_delete=models.PROTECT, related_name='reviews'
)
customer = models.ForeignKey(
Customer, on_delete=models.PROTECT, related_name='reviews'
)
rating = models.PositiveSmallIntegerField(
validators=[MinValueValidator(1), MaxValueValidator(5)]
)
text = models.TextField(null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"Review by {self.customer} for {self.product}: {self.rating}/5"
class Meta:
ordering = ['-created_at']
unique_together = (('product', 'customer'),)
Шаг 2: Admin для Review
from .models import (
Category, Supplier, Product, ProductDetail,
Address, Customer, Order, OrderItem, Review
)
@admin.register(Review)
class ReviewAdmin(admin.ModelAdmin):
list_display = ('product', 'customer', 'rating', 'created_at')
search_fields = ('product__name', 'customer__first_name', 'customer__last_name')
list_filter = ('rating', 'product')
ordering = ('-created_at',)
Шаг 3: Проверка уникальности
После создания двух отзывов от одного клиента на один товар Django вернёт ошибку валидации из-за unique_together. В Admin появится сообщение: "Review with this Product and Customer already exists."
Проверка в VS Code
Через терминал
python manage.py shell
from myapp.models import Review, Product, Customer
# Создать тестовый отзыв
p = Product.objects.first()
c = Customer.objects.first()
r = Review.objects.create(product=p, customer=c, rating=5, text="Отличный товар!")
print(r)
# Review by John Doe for Widget: 5/5
# Проверить все отзывы на продукт
reviews = p.reviews.all()
print(reviews)
Через Admin (браузер)
- Открыть
http://127.0.0.1:8000/admin/ - Раздел Reviews → Add Review
- Выбрать Product и Customer, указать рейтинг 1–5
- Сохранить — отзыв появится в списке
- Попробовать добавить второй отзыв с теми же Product и Customer — Django покажет ошибку уникальности
Отладка в VS Code (F5)
Создайте файл .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Django",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/manage.py",
"args": ["runserver"],
"django": true
}
]
}
Нажмите F5 — запустится Django-сервер с поддержкой точек останова. Откройте models.py, поставьте точку останова в методе __str__ модели Review и создайте отзыв через Admin.
Связь с теорией и примерами урока
- Теория: on_delete стратегии — PROTECT защищает Product и Customer от удаления, пока есть отзывы
- Примеры: Admin с list_display и search_fields по связанным моделям — паттерн
product__name - Старый vs Новый: unique_together — можно заменить на UniqueConstraint