gr421_kuaig 1 ano atrás
pai
commit
f170c59c5f

+ 3 - 0
.idea/misc.xml

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

+ 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>

BIN
store/db.sqlite3


BIN
store/media/avatars/1675489758_gas-kvas-com-p-izobrazheniya-i-kartinki-na-fonovii-risuno-41.jpg


BIN
store/media/avatars/1675489758_gas-kvas-com-p-izobrazheniya-i-kartinki-na-fonovii-risuno-41_Yh43VTJ.jpg


BIN
store/media/avatars/1675489758_gas-kvas-com-p-izobrazheniya-i-kartinki-na-fonovii-risuno-41_dg6SXTr.jpg


BIN
store/media/avatars/578a963b594a11ee927d363fac71b015_upscaled.jfif


BIN
store/media/avatars/578a963b594a11ee927d363fac71b015_upscaled_KuqpZSr.jfif


BIN
store/media/avatars/578a963b594a11ee927d363fac71b015_upscaled_ZyBemn1.jfif


BIN
store/media/avatars/578a963b594a11ee927d363fac71b015_upscaled_pEo8zgo.jfif


+ 11 - 1
store/store/settings.py

@@ -37,6 +37,7 @@ INSTALLED_APPS = [
     "django.contrib.sessions",
     "django.contrib.messages",
     "django.contrib.staticfiles",
+    "stre.apps.StreConfig"
 ]
 
 MIDDLEWARE = [
@@ -103,7 +104,7 @@ AUTH_PASSWORD_VALIDATORS = [
 # Internationalization
 # https://docs.djangoproject.com/en/5.0/topics/i18n/
 
-LANGUAGE_CODE = "en-us"
+LANGUAGE_CODE = "ru-ru"
 
 TIME_ZONE = "UTC"
 
@@ -121,3 +122,12 @@ STATIC_URL = "static/"
 # https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
 
 DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
+
+MEDIA_URL = 'media/'
+MEDIA_ROOT = BASE_DIR / 'media'
+
+AUTH_USER_MODEL = 'stre.User'
+
+LOGIN_REDIRECT_URL = 'index'
+LOGIN_URL = 'login'
+LOGOUT_REDIRECT_URL = 'index'

+ 7 - 1
store/store/urls.py

@@ -14,9 +14,15 @@ Including another URLconf
     1. Import the include() function: from django.urls import include, path
     2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
 """
+from django.conf import settings
+from django.conf.urls.static import static
 from django.contrib import admin
-from django.urls import path
+from django.urls import path, include
 
 urlpatterns = [
     path("admin/", admin.site.urls),
+    path('', include('stre.urls'))
 ]
+
+if settings.DEBUG:
+    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

+ 25 - 0
store/stre/forms.py

@@ -0,0 +1,25 @@
+from django.contrib.auth import get_user_model
+from django.contrib.auth.forms import UserCreationForm
+from django import forms
+
+from .models import *
+
+
+class RegistrationForm(UserCreationForm):
+    username = forms.CharField(label='Логин')
+    password1 = forms.CharField(label='Придумайте пароль', widget=forms.PasswordInput())
+    password2 = forms.CharField(label='Придумайте пароль', widget=forms.PasswordInput())
+
+    class Meta:
+        model = get_user_model()
+        fields = ('username', 'name', 'surname', 'avatar', 'password1', 'password2')
+
+        labels = {
+            'name': 'Имя',
+            'surname': 'Фамилия',
+            'avatar': 'Аватарка'
+        }
+
+class ProfileForm(forms.ModelForm):
+    class Meta:
+        fields = ('username', 'name', 'surname', 'avatar', 'password')

+ 164 - 0
store/stre/migrations/0001_initial.py

@@ -0,0 +1,164 @@
+# Generated by Django 5.0 on 2023-12-26 06:20
+
+import django.contrib.auth.models
+import django.utils.timezone
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+    initial = True
+
+    dependencies = [
+        ("auth", "0012_alter_user_first_name_max_length"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="Service",
+            fields=[
+                (
+                    "id",
+                    models.BigAutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                (
+                    "name",
+                    models.CharField(
+                        blank=True, max_length=1000, verbose_name="Название услуги"
+                    ),
+                ),
+                (
+                    "image",
+                    models.ImageField(upload_to="services", verbose_name="Картинка"),
+                ),
+                ("text", models.TextField(blank=True, verbose_name="Описание")),
+                (
+                    "date",
+                    models.DateTimeField(
+                        auto_now_add=True, verbose_name="Дата добавления на сайт"
+                    ),
+                ),
+            ],
+        ),
+        migrations.CreateModel(
+            name="User",
+            fields=[
+                (
+                    "id",
+                    models.BigAutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                (
+                    "last_login",
+                    models.DateTimeField(
+                        blank=True, null=True, verbose_name="last login"
+                    ),
+                ),
+                (
+                    "is_superuser",
+                    models.BooleanField(
+                        default=False,
+                        help_text="Designates that this user has all permissions without explicitly assigning them.",
+                        verbose_name="superuser status",
+                    ),
+                ),
+                (
+                    "first_name",
+                    models.CharField(
+                        blank=True, max_length=150, verbose_name="first name"
+                    ),
+                ),
+                (
+                    "last_name",
+                    models.CharField(
+                        blank=True, max_length=150, verbose_name="last name"
+                    ),
+                ),
+                (
+                    "email",
+                    models.EmailField(
+                        blank=True, max_length=254, verbose_name="email address"
+                    ),
+                ),
+                (
+                    "is_staff",
+                    models.BooleanField(
+                        default=False,
+                        help_text="Designates whether the user can log into this admin site.",
+                        verbose_name="staff status",
+                    ),
+                ),
+                (
+                    "is_active",
+                    models.BooleanField(
+                        default=True,
+                        help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.",
+                        verbose_name="active",
+                    ),
+                ),
+                (
+                    "date_joined",
+                    models.DateTimeField(
+                        default=django.utils.timezone.now, verbose_name="date joined"
+                    ),
+                ),
+                (
+                    "name",
+                    models.CharField(blank=True, max_length=100, verbose_name="Имя"),
+                ),
+                (
+                    "surname",
+                    models.CharField(
+                        blank=True, max_length=100, verbose_name="Фамилия"
+                    ),
+                ),
+                (
+                    "username",
+                    models.CharField(max_length=100, unique=True, verbose_name="Логин"),
+                ),
+                (
+                    "avatar",
+                    models.ImageField(upload_to="avatars", verbose_name="Аватарка"),
+                ),
+                ("password", models.CharField(max_length=100, verbose_name="Пароль")),
+                (
+                    "groups",
+                    models.ManyToManyField(
+                        blank=True,
+                        help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.",
+                        related_name="user_set",
+                        related_query_name="user",
+                        to="auth.group",
+                        verbose_name="groups",
+                    ),
+                ),
+                (
+                    "user_permissions",
+                    models.ManyToManyField(
+                        blank=True,
+                        help_text="Specific permissions for this user.",
+                        related_name="user_set",
+                        related_query_name="user",
+                        to="auth.permission",
+                        verbose_name="user permissions",
+                    ),
+                ),
+            ],
+            options={
+                "verbose_name": "user",
+                "verbose_name_plural": "users",
+                "abstract": False,
+            },
+            managers=[
+                ("objects", django.contrib.auth.models.UserManager()),
+            ],
+        ),
+    ]

+ 13 - 1
store/stre/models.py

@@ -1,3 +1,15 @@
+from django.contrib.auth.models import AbstractUser
 from django.db import models
 
-# Create your models here.
+class User(AbstractUser):
+    name = models.CharField(max_length=100, verbose_name="Имя", blank=True)
+    surname = models.CharField(max_length=100, verbose_name="Фамилия", blank=True)
+    username = models.CharField(max_length=100, unique=True, verbose_name="Логин")
+    avatar = models.ImageField(upload_to="avatars", verbose_name="Аватарка")
+    password = models.CharField(max_length=100, verbose_name="Пароль")
+
+class Service(models.Model):
+    name = models.CharField(max_length=1000, blank=True, verbose_name="Название услуги")
+    image = models.ImageField(upload_to="services", verbose_name="Картинка")
+    text = models.TextField(blank=True, verbose_name="Описание")
+    date = models.DateTimeField(auto_now_add=True, verbose_name="Дата добавления на сайт")

+ 4 - 0
store/stre/templates/all.html

@@ -0,0 +1,4 @@
+{% extends 'base.html' %}
+
+{% block content %}
+{% endblock %}

+ 28 - 0
store/stre/templates/base.html

@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html lang="ru">
+<head>
+    <meta charset="UTF-8">
+    <title>Фирма</title>
+    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
+</head>
+<body style="margin: 20px 0 0 40px;">
+    <div>
+        {% if user.is_authenticated %}
+        <nav style="display:flex; gap:20px;">
+            <a href="{% url 'index' %}">Главная</a>
+            <a href="{% url 'all' %}">Все товары и услуги</a>
+            <a href="{% url 'profile' user.pk %}">Профиль</a>
+            <a href="{% url 'logout' %}">Выйти</a>
+        </nav>
+        {% else %}
+        <nav style="display:flex; gap:20px;">
+            <a href="{% url 'index' %}">Главная</a>
+            <a href="{% url 'all' %}">Все товары и услуги</a>
+            <a href="{% url 'registration' %}">Зарегистрироваться</a>
+            <a href="{% url 'login' %}">Войти</a>
+        </nav>
+        {% endif %}
+    </div>
+    <div>{% block content %}{% endblock %}</div>
+</body>
+</html>

+ 4 - 0
store/stre/templates/details.html

@@ -0,0 +1,4 @@
+{% extends 'base.html' %}
+
+{% block content %}
+{% endblock %}

+ 33 - 0
store/stre/templates/index.html

@@ -0,0 +1,33 @@
+{% extends 'base.html' %}
+
+{% block content %}
+<h1>Главная страница</h1>
+
+<h3>Общее описание наших услуг:</h3>
+<p>Мы крутые, а товары и услуги у нас ещё круче.</p><br><br>
+
+<p>Последние 5 товаров:</p>
+{% for service in services %}
+    <p>{{ service.name }}</p>
+    <p><img src="{{ service.image.url }}" style="height:300px; weight:300px"></p>
+    <p>{{ service.text }}</p>
+{% endfor %}
+{% endblock %}
+
+{% block pagination %}
+    {% if is_paginated %}
+        <div>
+            <span>
+                {% if page_obj.has_previous %}
+                    <a href="{{request.path}}?page={{page.obj.previous_page_number}}"><--</a>
+                {% endif %}
+            <span>
+                Страница {{page_obj.number}} из {{page_obj.paginator.num_pages}}.
+            </span>
+                {% if page_obj.has_next %}
+                    <a href="{{request.path}}?page={{page.obj.next_page_number}}">--></a>
+                {% endif %}
+            </span>
+        </div>
+    {% endif %}
+{% endblock %}

+ 10 - 0
store/stre/templates/user/login.html

@@ -0,0 +1,10 @@
+{% extends 'base.html' %}
+
+{% block content %}
+<h1>Вход</h1>
+<form method="post">
+    {{ form.as_p }}
+    {% csrf_token %}
+    <button type="submit">Войти</button>
+</form>
+{% endblock %}

+ 4 - 0
store/stre/templates/user/profile.html

@@ -0,0 +1,4 @@
+{% extends 'base.html' %}
+
+{% block content %}
+{% endblock %}

+ 10 - 0
store/stre/templates/user/registration.html

@@ -0,0 +1,10 @@
+{% extends 'base.html' %}
+
+{% block content %}
+<h1>Регистрация</h1>
+<form method="post", enctype="multipart/form-data">
+    {{ form.as_p }}
+    {% csrf_token %}
+    <button type="submit">Зарегистрироваться</button>
+</form>
+{% endblock %}

+ 12 - 0
store/stre/urls.py

@@ -0,0 +1,12 @@
+from django.contrib.auth.views import LogoutView
+from django.urls import path
+from .views import *
+
+urlpatterns = [
+    path('', Index.as_view(), name='index'),
+    path('service', AllService.as_view(), name='all'),
+    path('register', Registration.as_view(), name='registration'),
+    path('login', LoginView.as_view(), name='login'),
+    path('logout', LogoutView.as_view(), name='logout'),
+    path('profile/<int:pk>', Profile.as_view(), name='profile')
+]

+ 40 - 1
store/stre/views.py

@@ -1,3 +1,42 @@
+from django.contrib.auth.forms import AuthenticationForm
+from django.contrib.auth.views import LoginView
 from django.shortcuts import render
+from django.urls import reverse_lazy
+from django.views.generic import ListView, CreateView, UpdateView
 
-# Create your views here.
+from .models import *
+from .forms import *
+
+class Index(ListView):
+    model = Service
+    template_name = 'index.html'
+    paginate_by = 5
+
+    def get_queryset(self):
+        return Service.objects.order_by('-date')
+
+    def index(self):
+        return render(self, 'index.html')
+
+class AllService(ListView):
+    def all(self):
+        return render(self, 'all.html')
+
+class Registration(CreateView):
+    form_class = RegistrationForm
+    template_name = 'user/registration.html'
+    success_url = reverse_lazy('login')
+
+    def registration(self):
+        return render(self, 'user/registration.html')
+
+class LoginView(LoginView):
+    form_class = AuthenticationForm
+    template_name = 'user/login.html'
+    success_url = reverse_lazy('profile')
+
+class Profile(UpdateView):
+    model = User
+    fields = ['username', 'name', 'surname', 'avatar']
+    success_urls = reverse_lazy('profile')
+    template_name = 'user/profile.html'