Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Django CI

on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-latest

services:
postgres:
image: postgres:13
env:
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432

steps:
- uses: actions/checkout@v2

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.9'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- name: Run tests
env:
DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres
SECRET_KEY: test-key
run: |
python manage.py test
Binary file modified .gitignore
Binary file not shown.
21 changes: 21 additions & 0 deletions debug.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import os
import sys

print("=== DEBUG INFO ===")
print("Current directory:", os.getcwd())
print("Directory contents:", os.listdir('.'))
print("Python path:", sys.path)

try:
from tplab2.wsgi import application
print("✅ SUCCESS: tplab2.wsgi imported successfully!")
except ImportError as e:
print("❌ ERROR importing tplab2.wsgi:", e)
print("Available modules:")
for item in os.listdir('.'):
if os.path.isdir(item):
print(f" - {item}/")
try:
print(f" Contents: {os.listdir(item)}")
except:
print(f" Cannot list contents")
Binary file added shop/__pycache__/__init__.cpython-313.pyc
Binary file not shown.
Binary file added shop/__pycache__/admin.cpython-313.pyc
Binary file not shown.
Binary file added shop/__pycache__/apps.cpython-313.pyc
Binary file not shown.
Binary file added shop/__pycache__/models.cpython-313.pyc
Binary file not shown.
Binary file added shop/__pycache__/urls.cpython-313.pyc
Binary file not shown.
Binary file added shop/__pycache__/views.cpython-313.pyc
Binary file not shown.
4 changes: 3 additions & 1 deletion shop/admin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from django.contrib import admin
from .models import Product # Импортируем модель Product

# Register your models here.
# Регистрируем модель Product в админке
admin.site.register(Product)
10 changes: 6 additions & 4 deletions shop/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Generated by Django 3.2.8 on 2021-10-06 17:32
# Generated by Django 5.2.7 on 2025-10-29 16:02

from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):
Expand All @@ -16,8 +16,10 @@ class Migration(migrations.Migration):
name='Product',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=200)),
('price', models.PositiveIntegerField()),
('name', models.CharField(max_length=100)),
('price', models.DecimalField(decimal_places=2, max_digits=10)),
('description', models.TextField(blank=True)),
('quantity', models.PositiveIntegerField(default=1)),
],
),
migrations.CreateModel(
Expand Down
18 changes: 18 additions & 0 deletions shop/migrations/0002_add_quantity_field.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.2.7 on 2025-10-29 16:04

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('shop', '0001_initial'),
]

operations = [
migrations.AddField(
model_name='product',
name='quantity',
field=models.PositiveIntegerField(default=1),
),
]
Binary file not shown.
Binary file added shop/migrations/__pycache__/__init__.cpython-313.pyc
Binary file not shown.
12 changes: 10 additions & 2 deletions shop/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@

# Create your models here.
class Product(models.Model):
name = models.CharField(max_length=200)
price = models.PositiveIntegerField()
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
description = models.TextField(blank=True)
quantity = models.PositiveIntegerField(default=1) # Добавляем это поле

def is_available(self):
return self.quantity > 0

def __str__(self):
return f"{self.name} ({self.quantity} шт.)"

class Purchase(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
Expand Down
14 changes: 11 additions & 3 deletions shop/templates/shop/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,24 @@ <h3>Список</h3>
<tr>
<td><p>Наименование</p></td>
<td><p>Цена</p></td>
<td></td>
<td><p>Количество</p></td>
<td><p>Действие</p></td>
</tr>
{% for p in products %}
<tr>
<td><p>{{ p.name }}</p></td>
<td><p>{{ p.price }}</p></td>
<td><p><a href="/buy/{{ p.id }}">Купить</a></p></td>
<td><p>{{ p.quantity }} шт.</p></td>
<td>
{% if p.quantity > 0 %}
<p><a href="/buy/{{ p.id }}">Купить</a></p>
{% else %}
<p style="color: red;">Нет в наличии</p>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
</div>
</body>
</html>
</html>
23 changes: 23 additions & 0 deletions shop/templates/shop/product_list.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<h1>Список</h1>
<table>
<tr>
<th>Наименование</th>
<th>Цена</th>
<th>Количество</th>
<th>Действие</th>
</tr>
{% for product in products %}
<tr>
<td>{{ product.name }}</td>
<td>{{ product.price }}</td>
<td>{{ product.quantity }} шт.</td>
<td>
{% if product.quantity > 0 %}
<a href="{% url 'buy_product' product.id %}">Купить</a>
{% else %}
<span style="color: red;">Нет в наличии</span>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
42 changes: 20 additions & 22 deletions shop/templates/shop/purchase_form.html
Original file line number Diff line number Diff line change
@@ -1,28 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Покупка</title>
<title>Оформление покупки</title>
</head>
<body>
<div>
<h3>Покупка</h3>
<form method="post">{% csrf_token %}
<input type="hidden" value="{{ view.kwargs.product_id }}" name="product" />
<table>
<tr>
<td><p>Введите свое имя </p></td>
<td><input type="text" name="person" /> </td>
</tr>
<tr>
<td><p>Введите адрес доставки:</p></td>
<td>
<input type="text" name="address" />
</td>
</tr>
<tr><td><input type="submit" value="Отправить" /> </td><td></td></tr>
</table>
</form>
</div>
<h1>Оформление покупки: {{ product.name }}</h1>
<p>Цена: {{ product.price }} руб.</p>
<p>Осталось: {{ product.quantity }} шт.</p>

<form method="post">
{% csrf_token %}
<div>
<label>Ваше имя:</label>
<input type="text" name="person" required>
</div>
<div>
<label>Адрес доставки:</label>
<input type="text" name="address" required>
</div>
<button type="submit">Подтвердить покупку</button>
</form>

<a href="/">Вернуться к списку товаров</a>
</body>
</html>
</html>
4 changes: 2 additions & 2 deletions shop/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

urlpatterns = [
path('', views.index, name='index'),
path('buy/<int:product_id>/', views.PurchaseCreate.as_view(), name='buy'),
]
path('buy/<int:product_id>/', views.buy_product, name='buy'), # ← ИЗМЕНИТЬ ЭТУ СТРОКУ
]
36 changes: 35 additions & 1 deletion shop/views.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from django.shortcuts import render
from django.shortcuts import render, get_object_or_404 # ← ДОБАВИТЬ ЭТО
from django.http import HttpResponse
from django.views.generic.edit import CreateView

from .models import Product, Purchase


# Create your views here.
def index(request):
products = Product.objects.all()
Expand All @@ -19,3 +20,36 @@ def form_valid(self, form):
self.object = form.save()
return HttpResponse(f'Спасибо за покупку, {self.object.person}!')

def buy_product(request, product_id):
product = get_object_or_404(Product, id=product_id)

# Проверяем наличие товара
if product.quantity <= 0:
return HttpResponse("Этот товар закончился!", status=400)

# Если GET запрос - показываем форму
if request.method == 'GET':
return render(request, 'shop/purchase_form.html', {
'product': product
})

# Если POST запрос - обрабатываем покупку
elif request.method == 'POST':
person = request.POST.get('person')
address = request.POST.get('address')

if not person or not address:
return HttpResponse("Заполните все поля!", status=400)

# Уменьшаем количество товара
product.quantity -= 1
product.save()

# Создаем запись о покупке
Purchase.objects.create(
product=product,
person=person,
address=address
)

return HttpResponse(f"Спасибо за покупку, {person}! Товар '{product.name}' отправлен по адресу: {address}. Осталось: {product.quantity} шт.")
Loading