locadm 1 年之前
當前提交
96db839a44

+ 0 - 0
.gitignore


+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 6 - 0
.idea/inspectionProfiles/profiles_settings.xml

@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+  <settings>
+    <option name="USE_PROJECT_PROFILE" value="false" />
+    <version value="1.0" />
+  </settings>
+</component>

+ 7 - 0
.idea/misc.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Black">
+    <option name="sdkName" value="Python 3.12 (pythonProject)" />
+  </component>
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (pythonProject)" project-jdk-type="Python SDK" />
+</project>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/pythonProject.iml" filepath="$PROJECT_DIR$/.idea/pythonProject.iml" />
+    </modules>
+  </component>
+</project>

+ 10 - 0
.idea/pythonProject.iml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.venv" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

+ 0 - 0
Myshop/Myshop/__init__.py


+ 16 - 0
Myshop/Myshop/asgi.py

@@ -0,0 +1,16 @@
+"""
+ASGI config for Myshop project.
+
+It exposes the ASGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
+"""
+
+import os
+
+from django.core.asgi import get_asgi_application
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Myshop.settings")
+
+application = get_asgi_application()

+ 128 - 0
Myshop/Myshop/settings.py

@@ -0,0 +1,128 @@
+"""
+Django settings for Myshop project.
+
+Generated by 'django-admin startproject' using Django 5.0.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/5.0/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/5.0/ref/settings/
+"""
+
+from pathlib import Path
+
+# Build paths inside the project like this: BASE_DIR / 'subdir'.
+BASE_DIR = Path(__file__).resolve().parent.parent
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = "django-insecure-5swxovul!jgryhx%@9j153gnk(ho*)*n*bz8m#smr*=6q^csgg"
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = [
+    "bootstrap4",
+    "shop",
+    "django.contrib.admin",
+    "django.contrib.auth",
+    "django.contrib.contenttypes",
+    "django.contrib.sessions",
+    "django.contrib.messages",
+    "django.contrib.staticfiles",
+]
+
+MIDDLEWARE = [
+    "django.middleware.security.SecurityMiddleware",
+    "django.contrib.sessions.middleware.SessionMiddleware",
+    "django.middleware.common.CommonMiddleware",
+    "django.middleware.csrf.CsrfViewMiddleware",
+    "django.contrib.auth.middleware.AuthenticationMiddleware",
+    "django.contrib.messages.middleware.MessageMiddleware",
+    "django.middleware.clickjacking.XFrameOptionsMiddleware",
+]
+
+ROOT_URLCONF = "Myshop.urls"
+
+TEMPLATES = [
+    {
+        "BACKEND": "django.template.backends.django.DjangoTemplates",
+        "DIRS": [],
+        "APP_DIRS": True,
+        "OPTIONS": {
+            "context_processors": [
+                "django.template.context_processors.debug",
+                "django.template.context_processors.request",
+                "django.contrib.auth.context_processors.auth",
+                "django.contrib.messages.context_processors.messages",
+            ],
+        },
+    },
+]
+
+WSGI_APPLICATION = "Myshop.wsgi.application"
+
+
+# Database
+# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
+
+DATABASES = {
+    "default": {
+        "ENGINE": "django.db.backends.sqlite3",
+        "NAME": BASE_DIR / "db.sqlite3",
+    }
+}
+
+
+# Password validation
+# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+    {
+        "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
+    },
+    {
+        "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
+    },
+    {
+        "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
+    },
+    {
+        "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
+    },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/5.0/topics/i18n/
+
+LANGUAGE_CODE = "en-us"
+
+TIME_ZONE = "UTC"
+
+USE_I18N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/5.0/howto/static-files/
+
+STATIC_URL = "static/"
+
+# Default primary key field type
+# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
+
+DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
+
+LOGIN_REDIRECT_URL = "/"
+LOGOUT_REDIRECT_URL = "/"

+ 7 - 0
Myshop/Myshop/urls.py

@@ -0,0 +1,7 @@
+from django.contrib import admin
+from django.urls import include, path
+
+urlpatterns = [
+    path('admin/', admin.site.urls),
+    path('', include('shop.urls')),
+]

+ 16 - 0
Myshop/Myshop/wsgi.py

@@ -0,0 +1,16 @@
+"""
+WSGI config for Myshop project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Myshop.settings")
+
+application = get_wsgi_application()

二進制
Myshop/db.sqlite3


+ 22 - 0
Myshop/manage.py

@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+"""Django's command-line utility for administrative tasks."""
+import os
+import sys
+
+
+def main():
+    """Run administrative tasks."""
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Myshop.settings")
+    try:
+        from django.core.management import execute_from_command_line
+    except ImportError as exc:
+        raise ImportError(
+            "Couldn't import Django. Are you sure it's installed and "
+            "available on your PYTHONPATH environment variable? Did you "
+            "forget to activate a virtual environment?"
+        ) from exc
+    execute_from_command_line(sys.argv)
+
+
+if __name__ == "__main__":
+    main()

+ 0 - 0
Myshop/shop/__init__.py


+ 3 - 0
Myshop/shop/admin.py

@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.

+ 6 - 0
Myshop/shop/apps.py

@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class ShopConfig(AppConfig):
+    default_auto_field = "django.db.models.BigAutoField"
+    name = "shop"

+ 7 - 0
Myshop/shop/forms.py

@@ -0,0 +1,7 @@
+from django import forms
+from .models import Order
+
+class OrderForm(forms.ModelForm):
+    class Meta:
+        model = Order
+        fields = ['product']

+ 84 - 0
Myshop/shop/migrations/0001_initial.py

@@ -0,0 +1,84 @@
+# Generated by Django 5.0 on 2023-12-26 04:46
+
+import django.db.models.deletion
+from django.conf import settings
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+    initial = True
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="Product",
+            fields=[
+                (
+                    "id",
+                    models.BigAutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("title", models.CharField(max_length=255)),
+                ("description", models.TextField()),
+                ("image", models.ImageField(upload_to="product_images/")),
+                ("price", models.DecimalField(decimal_places=2, max_digits=10)),
+            ],
+        ),
+        migrations.CreateModel(
+            name="Order",
+            fields=[
+                (
+                    "id",
+                    models.BigAutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("order_date", models.DateTimeField(auto_now_add=True)),
+                (
+                    "user",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to=settings.AUTH_USER_MODEL,
+                    ),
+                ),
+                (
+                    "product",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, to="shop.product"
+                    ),
+                ),
+            ],
+        ),
+        migrations.CreateModel(
+            name="UserProfile",
+            fields=[
+                (
+                    "id",
+                    models.BigAutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("avatar", models.ImageField(upload_to="user_avatars/")),
+                (
+                    "user",
+                    models.OneToOneField(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to=settings.AUTH_USER_MODEL,
+                    ),
+                ),
+            ],
+        ),
+    ]

+ 33 - 0
Myshop/shop/migrations/0002_remove_order_product_remove_order_user_and_more.py

@@ -0,0 +1,33 @@
+# Generated by Django 5.0 on 2023-12-26 04:58
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("shop", "0001_initial"),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name="order",
+            name="product",
+        ),
+        migrations.RemoveField(
+            model_name="order",
+            name="user",
+        ),
+        migrations.RemoveField(
+            model_name="userprofile",
+            name="user",
+        ),
+        migrations.DeleteModel(
+            name="Product",
+        ),
+        migrations.DeleteModel(
+            name="Order",
+        ),
+        migrations.DeleteModel(
+            name="UserProfile",
+        ),
+    ]

+ 85 - 0
Myshop/shop/migrations/0003_initial.py

@@ -0,0 +1,85 @@
+# Generated by Django 5.0 on 2023-12-26 05:03
+
+import django.db.models.deletion
+from django.conf import settings
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+    initial = True
+
+    dependencies = [
+        ("shop", "0002_remove_order_product_remove_order_user_and_more"),
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="Product",
+            fields=[
+                (
+                    "id",
+                    models.BigAutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("title", models.CharField(max_length=255)),
+                ("description", models.TextField()),
+                ("image", models.ImageField(upload_to="product_images/")),
+                ("price", models.DecimalField(decimal_places=2, max_digits=10)),
+            ],
+        ),
+        migrations.CreateModel(
+            name="Order",
+            fields=[
+                (
+                    "id",
+                    models.BigAutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("order_date", models.DateTimeField(auto_now_add=True)),
+                (
+                    "user",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to=settings.AUTH_USER_MODEL,
+                    ),
+                ),
+                (
+                    "product",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, to="shop.product"
+                    ),
+                ),
+            ],
+        ),
+        migrations.CreateModel(
+            name="UserProfile",
+            fields=[
+                (
+                    "id",
+                    models.BigAutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("avatar", models.ImageField(upload_to="user_avatars/")),
+                (
+                    "user",
+                    models.OneToOneField(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to=settings.AUTH_USER_MODEL,
+                    ),
+                ),
+            ],
+        ),
+    ]

+ 0 - 0
Myshop/shop/migrations/__init__.py


+ 17 - 0
Myshop/shop/models.py

@@ -0,0 +1,17 @@
+from django.db import models
+from django.contrib.auth.models import User
+
+class Product(models.Model):
+    title = models.CharField(max_length=255)
+    description = models.TextField()
+    image = models.ImageField(upload_to='product_images/')
+    price = models.DecimalField(max_digits=10, decimal_places=2)
+
+class UserProfile(models.Model):
+    user = models.OneToOneField(User, on_delete=models.CASCADE)
+    avatar = models.ImageField(upload_to='user_avatars/')
+
+class Order(models.Model):
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
+    product = models.ForeignKey(Product, on_delete=models.CASCADE)
+    order_date = models.DateTimeField(auto_now_add=True)

+ 21 - 0
Myshop/shop/templates/base.html

@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>{% block title %} Shop {% endblock %}</title>
+</head>
+<body>
+<header>
+    <a href="{% url 'home' %}">Главная страница</a>
+    <a href="{% url 'profile' %}">Личный кабинет</a>
+    <a href="{% url 'service' %}">Услуги</a>
+    {% if user.is_authenticated %}
+    <a href="{% url 'logout' %}">Выход</a>
+    {% else %}
+    <a href="{% url 'register' %}">Регистрация</a>
+    <a href="{% url 'login' %}">Вход</a>
+    {% endif %}
+</header>
+{% block content %}{% endblock %}
+</body>
+</html>

+ 9 - 0
Myshop/shop/templates/shop/home.html

@@ -0,0 +1,9 @@
+{% extends 'base.html' %}
+
+{% block content %}
+  <h1>Добро пожаловать </h1>
+<p>Наш сайт нацелен на продажу и размещение товаров разлчных категорий</p>
+
+
+<a href="order"></a>
+{% endblock %}

+ 10 - 0
Myshop/shop/templates/shop/login.html

@@ -0,0 +1,10 @@
+{% extends 'base.html' %}
+
+{% block content %}
+  <h2>Вход в систему</h2>
+  <form method="post" action="{% url 'login' %}">
+    {% csrf_token %}
+    {{ form.as_p }}
+    <button type="submit">Login</button>
+  </form>
+{% endblock %}

+ 10 - 0
Myshop/shop/templates/shop/order.html

@@ -0,0 +1,10 @@
+{% extends 'base.html' %}
+
+{% block content %}
+  <h2>Заказ {{ product.title }}</h2>
+  <form method="post" action="{% url 'order' product.id %}">
+    {% csrf_token %}
+    {{ form.as_p }}
+    <button type="submit">Разместить заказ</button>
+  </form>
+{% endblock %}

+ 9 - 0
Myshop/shop/templates/shop/product_detail.html

@@ -0,0 +1,9 @@
+{% extends 'base.html' %}
+
+{% block content %}
+  <h2>{{ product.title }}</h2>
+  <img src="{{ product.image.url }}" alt="{{ product.title }}">
+  <p>{{ product.description }}</p>
+  <p>Price: ${{ product.price }}</p>
+  <a href="{% url 'order' product.id %}">Заказать сейчас!</a>
+{% endblock %}

+ 13 - 0
Myshop/shop/templates/shop/profile.html

@@ -0,0 +1,13 @@
+{% extends 'base.html' %}
+
+{% block content %}
+  <h2>Личный кабинет</h2>
+  <p>Добрый день, {{ user.username }}!</p>
+  <p>Фото: <img src="{{ user.userprofile.avatar.url }}" alt="{{ user.username }} Avatar"></p>
+  <h3>Ваши заказы:</h3>
+  <ul>
+    {% for order in user.order_set.all %}
+      <li>{{ order.product.title }} - {{ order.order_date }}</li>
+    {% endfor %}
+  </ul>
+{% endblock %}

+ 10 - 0
Myshop/shop/templates/shop/register.html

@@ -0,0 +1,10 @@
+{% extends 'base.html' %}
+
+{% block content %}
+  <h2>Register</h2>
+  <form method="post" action="{% url 'register' %}">
+    {% csrf_token %}
+    {{ form.as_p }}
+    <button type="submit">Register</button>
+  </form>
+{% endblock %}

+ 6 - 0
Myshop/shop/templates/shop/search_result.html

@@ -0,0 +1,6 @@
+{% extends 'base.html' %}
+
+{% block content %}
+  <h2>Search Results</h2>
+
+{% endblock %}

+ 14 - 0
Myshop/shop/templates/shop/service.html

@@ -0,0 +1,14 @@
+{% extends 'base.html' %}
+
+{% block content %}
+  <h2>Наш товар/Услуги</h2>
+<a href="{% url 'search_result' %}">Поиск</a>
+  {% for product in products %}
+    <div>
+      <h3>{{ product.title }}</h3>
+      <img src="{{ product.image.url }}" alt="{{ product.title }}">
+      <p>{{ product.description }}</p>
+      <a href="{% url 'product_detail' product.id %}">Детали</a>
+    </div>
+  {% endfor %}
+{% endblock %}

+ 3 - 0
Myshop/shop/tests.py

@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.

+ 14 - 0
Myshop/shop/urls.py

@@ -0,0 +1,14 @@
+from django.urls import path
+from . import views
+
+urlpatterns = [
+    path('', views.home, name='home'),
+    path('register/', views.register, name='register'),
+    path('login/', views.login, name='login'),
+    path('service/', views.service, name='service'),
+    path('service/<int:product_id>/', views.product_detail, name='product_detail'),
+    path('search_result/', views.search_result, name='search_result'),
+    path('profile/', views.profile, name='profile'),
+    path('logout/', views.logout_view, name='logout'),
+
+]

+ 67 - 0
Myshop/shop/views.py

@@ -0,0 +1,67 @@
+from django.contrib.auth.views import LoginView
+from django.shortcuts import render, redirect
+from django.contrib.auth import authenticate, login, logout
+from django.contrib.auth.forms import UserCreationForm
+from django.contrib.auth.decorators import login_required
+from .forms import OrderForm
+from .models import Product, Order
+
+def home(request):
+    return render(request, 'shop/home.html')
+
+def search_result(request):
+    return render(request, 'shop/search_result.html')
+def register(request):
+    if request.method == 'POST':
+        form = UserCreationForm(request.POST)
+        if form.is_valid():
+            user = form.save()
+            login(request, user)
+            return redirect('home')
+    else:
+        form = UserCreationForm()
+    return render(request, 'shop/register.html', {'form': form})
+
+@login_required
+def profile(request):
+    # Ваш код для страницы профиля
+    return render(request, 'shop/profile.html')
+
+login = LoginView.as_view(template_name='shop/login.html')
+
+def service(request):
+    products = Product.objects.all()
+    return render(request, 'shop/service.html', {'products': products})
+
+def product_detail(request, product_id):
+    product = Product.objects.get(pk=product_id)
+    return render(request, 'shop/product_detail.html', {'product': product})
+
+@login_required
+def order(request, product_id):
+    product = Product.objects.get(pk=product_id)
+    if request.method == 'POST':
+        form = OrderForm(request.POST)
+        if form.is_valid():
+            order = form.save(commit=False)
+            order.user = request.user
+            order.product = product
+            order.save()
+            return redirect('profile')
+    else:
+        form = OrderForm()
+    return render(request, 'shop/order.html', {'form': form, 'product': product})
+
+def logout_view(request):
+    logout(request)
+    return redirect('home')
+
+def login_view(request):
+    if request.method == 'POST':
+        username = request.POST['username']
+        password = request.POST['password']
+        user = authenticate(request, username=username, password=password)
+        if user is not None:
+            login(request, user)
+            return redirect('home')
+    return render(request, 'shop/login.html')