From 8eab5e83de703feadbd6a0958c27addf03bf3983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B9=20=D0=9A=D1=80?= =?UTF-8?q?=D1=83=D0=B3=D0=BB=D0=BE=D0=B2?= Date: Sun, 26 May 2024 00:08:38 +0300 Subject: [PATCH 1/3] new script --- api_yamdb/data/comments.csv | 2 +- api_yamdb/data/review.csv | 2 +- api_yamdb/data/titles.csv | 2 +- api_yamdb/data/users.csv | 12 +- .../reviews/management/commands/import-csv.py | 157 +++++++++++++----- 5 files changed, 128 insertions(+), 47 deletions(-) diff --git a/api_yamdb/data/comments.csv b/api_yamdb/data/comments.csv index 930fc05..e8179a8 100644 --- a/api_yamdb/data/comments.csv +++ b/api_yamdb/data/comments.csv @@ -1,4 +1,4 @@ -id,review_id,text,author_id,pub_date +id,review_id,text,author,pub_date 1,6,"Ничего подобного, в фильме всё не так, и программирование тут вообще ни при чём!",102,2020-01-13T23:20:02.422Z 2,6,"Ну надо же, не нашлось ничего лучшего, кроме как прокомментировать разговор про гамбургеры, будто в фильме ничего важнее этого нет",101,2020-01-13T23:20:02.422Z 3,6,"Кстати, а что такое ""четверть фунта""? В граммах это сколько?",103,2020-01-13T23:20:02.422Z \ No newline at end of file diff --git a/api_yamdb/data/review.csv b/api_yamdb/data/review.csv index 9693772..b1d9ad2 100644 --- a/api_yamdb/data/review.csv +++ b/api_yamdb/data/review.csv @@ -1,4 +1,4 @@ -id,title_id,text,author_id,score,pub_date +id,title_id,text,author,score,pub_date 1,1,"Ставлю десять звёзд! ...Эти голоса были чище и светлее тех, о которых мечтали в этом сером, убогом месте. Как будто две птички влетели и своими голосами развеяли стены наших клеток, и на короткий миг каждый человек в Шоушенке почувствовал себя свободным.",100,10,2019-09-24T21:08:21.567Z 2,1,"Не привыкай diff --git a/api_yamdb/data/titles.csv b/api_yamdb/data/titles.csv index a02e83d..8a31c9c 100644 --- a/api_yamdb/data/titles.csv +++ b/api_yamdb/data/titles.csv @@ -1,4 +1,4 @@ -id,name,year,category_id +id,name,year,category 1,Побег из Шоушенка,1994,1 2,Крестный отец,1972,1 3,12 разгневанных мужчин,1957,1 diff --git a/api_yamdb/data/users.csv b/api_yamdb/data/users.csv index 70c65a1..b52438e 100644 --- a/api_yamdb/data/users.csv +++ b/api_yamdb/data/users.csv @@ -1,6 +1,6 @@ -id,username,email,role,bio,first_name,last_name,password,is_staff,is_superuser,is_active,date_joined -100,bingobongo,bingobongo@yamdb.fake,user,,,,0,0,0,1,0 -101,capt_obvious,capt_obvious@yamdb.fake,admin,,,,0,0,0,1,0 -102,faust,faust@yamdb.fake,user,,,,0,0,0,1,0 -103,reviewer,reviewer@yamdb.fake,user,,,,0,0,0,1,0 -104,angry,angry@yamdb.fake,moderator,,,,0,0,0,1,0 \ No newline at end of file +id,username,email,role,bio,first_name,last_name +100,bingobongo,bingobongo@yamdb.fake,user,,, +101,capt_obvious,capt_obvious@yamdb.fake,admin,,, +102,faust,faust@yamdb.fake,user,,, +103,reviewer,reviewer@yamdb.fake,user,,, +104,angry,angry@yamdb.fake,moderator,,, \ No newline at end of file diff --git a/api_yamdb/reviews/management/commands/import-csv.py b/api_yamdb/reviews/management/commands/import-csv.py index d920642..7cedfe0 100644 --- a/api_yamdb/reviews/management/commands/import-csv.py +++ b/api_yamdb/reviews/management/commands/import-csv.py @@ -4,53 +4,134 @@ Импортирует из CSV файлов в базу данных SQLite. """ import csv +from random import randint import sqlite3 from django.core.management.base import BaseCommand from django.conf import settings path = str(settings.BASE_DIR) + '/data/' -files = ('category.csv', 'genre.csv', 'titles.csv', - 'genre_title.csv', 'review.csv', 'comments.csv', 'users.csv') -tables = ('reviews_category', 'reviews_genre', 'reviews_title', - 'reviews_title_genre', 'reviews_review', 'reviews_comment', - 'reviews_user') - - -def import_csv_to_sqlite(csv_file, table_name): - """Импортирует данные из CSV файла в базу данных SQLite.""" - conn = sqlite3.connect(str(settings.BASE_DIR) + '/db.sqlite3') - cursor = conn.cursor() - cursor.execute( - f"SELECT name FROM sqlite_master WHERE type='table'" - f"AND name='{table_name}';" - ) - if not cursor.fetchone(): - print(f'Table {table_name} does not exist. Skipping {csv_file}.') - conn.close() - return - with open(csv_file, 'r', encoding='utf-8') as file: - csv_reader = csv.reader(file) - header = next(csv_reader) - columns = ', '.join(header) - for row in csv_reader: - size = ', '.join(['?'] * len(row)) - cursor.execute( - f"INSERT INTO {table_name} ({columns}) VALUES ({size})", row - ) - conn.commit() - conn.close() - class Command(BaseCommand): """Команда для импорта данных из CSV файлов в базу данных SQLite.""" def handle(self, *args, **kwargs) -> None: """Обрабатывает импорт данных из CSV-файлов в базу данных SQLite.""" - for file, table in zip(files, tables): - try: - print('start download', file) - import_csv_to_sqlite(path + file, table) - print('finish download', file) - except Exception as e: - print(e) + + conn = sqlite3.connect(str(settings.BASE_DIR) + '/db.sqlite3') + cursor = conn.cursor() + + with open( + f'{path}category.csv', 'r', newline='', encoding='utf-8' + ) as csvfile: + reader_category = csv.DictReader(csvfile, delimiter=',') + to_db_category = [ + (row['id'], row['name'], row['slug']) + for row in reader_category + ] + + with open(f'{path}genre.csv', 'r', newline='', encoding='utf-8') as csvfile: + reader_genre = csv.DictReader(csvfile, delimiter=',') + to_db_genre = [ + (row['id'], row['name'], row['slug']) + for row in reader_genre + ] + + with open( + f'{path}titles.csv', 'r', newline='', encoding='utf-8' + ) as csvfile: + reader_titles = csv.DictReader(csvfile, delimiter=',') + to_db_titles = [ + (row['id'], row['name'], '', row['category'], + row['year']) + for row in reader_titles + ] + + with open( + f'{path}genre_title.csv', 'r', newline='', encoding='utf-8' + ) as csvfile: + reader_genre_title = csv.DictReader(csvfile, delimiter=',') + to_db_genre_title = [ + (row['id'], row['title_id'], row['genre_id']) + for row in reader_genre_title + ] + + with open( + f'{path}review.csv', 'r', newline='', encoding='utf-8' + ) as csvfile: + reader_review = csv.DictReader(csvfile, delimiter=',') + to_db_review = [ + (row['id'], row['text'], row['score'], row['pub_date'], + row['author'], row['title_id']) + for row in reader_review + ] + + with open( + f'{path}comments.csv', 'r', newline='', encoding='utf-8' + ) as csvfile: + reader_comments = csv.DictReader(csvfile, delimiter=',') + to_db_comments = [ + (row['id'], row['text'], row['pub_date'], + row['author'], row['review_id']) + for row in reader_comments + ] + + with open( + f'{path}users.csv', 'r', newline='', encoding='utf-8' + ) as csvfile: + reader_users = csv.DictReader(csvfile, delimiter=',') + to_db_users = [ + (row['id'], '', '', '', + row['username'], row['first_name'], row['last_name'], + '', '', '', row['bio'], + row['role'], str(randint(1000000, 10000000)), row['email']) + for row in reader_users + ] + + cursor.executemany( + 'INSERT INTO reviews_category ' + '(id, name, slug) VALUES (?, ?, ?)', + to_db_category + ) + conn.commit() + cursor.executemany( + 'INSERT INTO reviews_genre (id, name, slug)' + ' VALUES (?, ?, ?)', + to_db_genre + ) + conn.commit() + cursor.executemany( + 'INSERT INTO reviews_title (id, name, description, category_id, year)' + ' VALUES (?, ?, ?, ?, ?)', + to_db_titles + ) + conn.commit() + cursor.executemany( + 'INSERT INTO reviews_title_genre (id, title_id, genre_id)' + ' VALUES (?, ?, ?)', + to_db_genre_title + ) + conn.commit() + cursor.executemany( + 'INSERT INTO reviews_review ' + '(id, text, score, pub_date, author_id, title_id)' + ' VALUES (?, ?, ?, ?, ?, ?)', + to_db_review + ) + conn.commit() + cursor.executemany( + 'INSERT INTO reviews_comment (id, text, pub_date, author_id, review_id)' + ' VALUES (?, ?, ?, ?, ?)', + to_db_comments + ) + conn.commit() + cursor.executemany( + 'INSERT INTO reviews_user (id, password, last_login, ' + 'is_superuser, username, first_name, last_name,' + 'is_staff, is_active, date_joined, bio,' + 'role, confirmation_code, email)' + ' VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', + to_db_users + ) + conn.commit() + conn.close() From 69f6b7bac7ecf34cd6ce8a91aef1abbd328d2ac0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B9=20=D0=9A=D1=80?= =?UTF-8?q?=D1=83=D0=B3=D0=BB=D0=BE=D0=B2?= Date: Sun, 26 May 2024 00:27:58 +0300 Subject: [PATCH 2/3] sorting import --- api_yamdb/api/serializers.py | 13 +- api_yamdb/api/urls.py | 12 +- api_yamdb/api/utils.py | 2 +- api_yamdb/api/views.py | 45 ++-- api_yamdb/api/viewsets.py | 2 +- api_yamdb/api_yamdb/urls.py | 1 - api_yamdb/reviews/admin.py | 2 +- .../reviews/management/commands/import-csv.py | 248 +++++++++--------- api_yamdb/reviews/migrations/0001_initial.py | 5 +- api_yamdb/reviews/models.py | 22 +- api_yamdb/reviews/validators.py | 3 +- 11 files changed, 177 insertions(+), 178 deletions(-) diff --git a/api_yamdb/api/serializers.py b/api_yamdb/api/serializers.py index 485f634..05205e7 100644 --- a/api_yamdb/api/serializers.py +++ b/api_yamdb/api/serializers.py @@ -7,16 +7,21 @@ """ from django.conf import settings - from rest_framework import serializers from api_yamdb.constants import ( MAX_LENGTH_EMAIL_ADDRESS, MAX_LENGTH_USERNAME, - MAX_VALUE_SCORE, - MIN_VALUE_SCORE, + MAX_VALUE_SCORE, MIN_VALUE_SCORE +) +from reviews.models import ( + Category, + Comment, + Genre, + Review, + Title, + User ) -from reviews.models import Category, Genre, Title, Comment, Review, User from reviews.validators import ValidateUsername, validate_year diff --git a/api_yamdb/api/urls.py b/api_yamdb/api/urls.py index 82ebbd5..027f4ae 100644 --- a/api_yamdb/api/urls.py +++ b/api_yamdb/api/urls.py @@ -1,14 +1,18 @@ """Модуль URL Определяет шаблоны URL для конечных точек API.""" from django.urls import include, path - from rest_framework.routers import DefaultRouter from api.views import ( - CategoryViewSet, GenreViewSet, TitleViewSet, CommentViewSet, - ReviewViewSet, UserViewSet, SignUpView, GetTokenView + CategoryViewSet, + CommentViewSet, + GenreViewSet, + GetTokenView, + ReviewViewSet, + SignUpView, + TitleViewSet, + UserViewSet ) - router_v1 = DefaultRouter() router_v1.register('categories', CategoryViewSet, basename='categories') router_v1.register('genres', GenreViewSet, basename='genres') diff --git a/api_yamdb/api/utils.py b/api_yamdb/api/utils.py index 95e4033..5a00408 100644 --- a/api_yamdb/api/utils.py +++ b/api_yamdb/api/utils.py @@ -1,5 +1,5 @@ -from django.core.mail import send_mail from django.conf import settings +from django.core.mail import send_mail def send_confirmation_code(user): diff --git a/api_yamdb/api/views.py b/api_yamdb/api/views.py index 005bc5d..4585147 100644 --- a/api_yamdb/api/views.py +++ b/api_yamdb/api/views.py @@ -8,52 +8,39 @@ """ from random import sample +from django.conf import settings from django.db import IntegrityError from django.db.models import Avg -from django.conf import settings from django.shortcuts import get_object_or_404 +from django_filters.rest_framework import DjangoFilterBackend from rest_framework import status from rest_framework.decorators import action from rest_framework.exceptions import ValidationError -from rest_framework.permissions import AllowAny, IsAuthenticated from rest_framework.filters import SearchFilter -from rest_framework.views import APIView +from rest_framework.permissions import SAFE_METHODS, AllowAny, IsAuthenticated from rest_framework.response import Response +from rest_framework.throttling import UserRateThrottle +from rest_framework.views import APIView +from rest_framework.viewsets import ModelViewSet from rest_framework_simplejwt.tokens import AccessToken from rest_framework_simplejwt.views import TokenObtainPairView -from rest_framework.viewsets import ModelViewSet -from rest_framework.permissions import SAFE_METHODS -from rest_framework.throttling import UserRateThrottle -from django_filters.rest_framework import DjangoFilterBackend -from api.viewsets import CRDSlugSearchViewSet from api.filters import TitleFilter -from api.serializers import ( - CategorySerializer, - GenreSerializer, - ReadTitleSerializer, - WriteTitleSerializer, - CommentSerializer, - ReviewSerializer, - SignUpSerializer, - GetTokenSerializer, - UserSerializer, - AdminUserSerializer -) from api.permissions import ( - AdminOrReadOnlyPermission, AdminModeratorAuthorPermission, + AdminOrReadOnlyPermission, IsAdminPermission ) -from api.utils import send_confirmation_code -from reviews.models import ( - Category, - Genre, - Title, - Review, - Comment, - User +from api.serializers import ( + AdminUserSerializer, CategorySerializer, + CommentSerializer, GenreSerializer, + GetTokenSerializer, ReadTitleSerializer, + ReviewSerializer, SignUpSerializer, + UserSerializer, WriteTitleSerializer ) +from api.utils import send_confirmation_code +from api.viewsets import CRDSlugSearchViewSet +from reviews.models import Category, Comment, Genre, Review, Title, User class CategoryViewSet(CRDSlugSearchViewSet): diff --git a/api_yamdb/api/viewsets.py b/api_yamdb/api/viewsets.py index f99e0ab..5af4fd6 100644 --- a/api_yamdb/api/viewsets.py +++ b/api_yamdb/api/viewsets.py @@ -1,5 +1,5 @@ """Модуль, содержащий представления для работы с конечными точками API.""" -from rest_framework import viewsets, mixins +from rest_framework import mixins, viewsets from rest_framework.filters import SearchFilter from .permissions import AdminOrReadOnlyPermission diff --git a/api_yamdb/api_yamdb/urls.py b/api_yamdb/api_yamdb/urls.py index 18771c4..688ed76 100644 --- a/api_yamdb/api_yamdb/urls.py +++ b/api_yamdb/api_yamdb/urls.py @@ -10,7 +10,6 @@ from django.urls import include, path from django.views.generic import TemplateView - urlpatterns = [ path('admin/', admin.site.urls), path( diff --git a/api_yamdb/reviews/admin.py b/api_yamdb/reviews/admin.py index 28b08fe..aace928 100644 --- a/api_yamdb/reviews/admin.py +++ b/api_yamdb/reviews/admin.py @@ -5,7 +5,7 @@ """ from django.contrib import admin -from .models import Category, Comment, Genre, Title, Review, User +from .models import Category, Comment, Genre, Review, Title, User @admin.register(Category) diff --git a/api_yamdb/reviews/management/commands/import-csv.py b/api_yamdb/reviews/management/commands/import-csv.py index 7cedfe0..ccf4b41 100644 --- a/api_yamdb/reviews/management/commands/import-csv.py +++ b/api_yamdb/reviews/management/commands/import-csv.py @@ -4,134 +4,142 @@ Импортирует из CSV файлов в базу данных SQLite. """ import csv -from random import randint import sqlite3 -from django.core.management.base import BaseCommand +from random import randint + from django.conf import settings +from django.core.management.base import BaseCommand path = str(settings.BASE_DIR) + '/data/' + +def import_csv(): + conn = sqlite3.connect(str(settings.BASE_DIR) + '/db.sqlite3') + cursor = conn.cursor() + + with open( + f'{path}category.csv', 'r', newline='', encoding='utf-8' + ) as csvfile: + reader_category = csv.DictReader(csvfile, delimiter=',') + to_db_category = [ + (row['id'], row['name'], row['slug']) + for row in reader_category + ] + + with open( + f'{path}genre.csv', 'r', newline='', encoding='utf-8' + ) as csvfile: + reader_genre = csv.DictReader(csvfile, delimiter=',') + to_db_genre = [ + (row['id'], row['name'], row['slug']) + for row in reader_genre + ] + + with open( + f'{path}titles.csv', 'r', newline='', encoding='utf-8' + ) as csvfile: + reader_titles = csv.DictReader(csvfile, delimiter=',') + to_db_titles = [ + (row['id'], row['name'], '', row['category'], + row['year']) + for row in reader_titles + ] + + with open( + f'{path}genre_title.csv', 'r', newline='', encoding='utf-8' + ) as csvfile: + reader_genre_title = csv.DictReader(csvfile, delimiter=',') + to_db_genre_title = [ + (row['id'], row['title_id'], row['genre_id']) + for row in reader_genre_title + ] + + with open( + f'{path}review.csv', 'r', newline='', encoding='utf-8' + ) as csvfile: + reader_review = csv.DictReader(csvfile, delimiter=',') + to_db_review = [ + (row['id'], row['text'], row['score'], row['pub_date'], + row['author'], row['title_id']) + for row in reader_review + ] + + with open( + f'{path}comments.csv', 'r', newline='', encoding='utf-8' + ) as csvfile: + reader_comments = csv.DictReader(csvfile, delimiter=',') + to_db_comments = [ + (row['id'], row['text'], row['pub_date'], + row['author'], row['review_id']) + for row in reader_comments + ] + + with open( + f'{path}users.csv', 'r', newline='', encoding='utf-8' + ) as csvfile: + reader_users = csv.DictReader(csvfile, delimiter=',') + to_db_users = [ + (row['id'], '', '', '', + row['username'], row['first_name'], row['last_name'], + '', '', '', row['bio'], + row['role'], str(randint(1000000, 10000000)), row['email']) + for row in reader_users + ] + + cursor.executemany( + 'INSERT INTO reviews_category ' + '(id, name, slug) VALUES (?, ?, ?)', + to_db_category + ) + conn.commit() + cursor.executemany( + 'INSERT INTO reviews_genre (id, name, slug)' + ' VALUES (?, ?, ?)', + to_db_genre + ) + conn.commit() + cursor.executemany( + 'INSERT INTO reviews_title (id, name, description, category_id, year)' + ' VALUES (?, ?, ?, ?, ?)', + to_db_titles + ) + conn.commit() + cursor.executemany( + 'INSERT INTO reviews_title_genre (id, title_id, genre_id)' + ' VALUES (?, ?, ?)', + to_db_genre_title + ) + conn.commit() + cursor.executemany( + 'INSERT INTO reviews_review ' + '(id, text, score, pub_date, author_id, title_id)' + ' VALUES (?, ?, ?, ?, ?, ?)', + to_db_review + ) + conn.commit() + cursor.executemany( + 'INSERT INTO reviews_comment ' + '(id, text, pub_date, author_id, review_id)' + ' VALUES (?, ?, ?, ?, ?)', + to_db_comments + ) + conn.commit() + cursor.executemany( + 'INSERT INTO reviews_user (id, password, last_login, ' + 'is_superuser, username, first_name, last_name,' + 'is_staff, is_active, date_joined, bio,' + 'role, confirmation_code, email)' + ' VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', + to_db_users + ) + conn.commit() + conn.close() + + class Command(BaseCommand): """Команда для импорта данных из CSV файлов в базу данных SQLite.""" def handle(self, *args, **kwargs) -> None: """Обрабатывает импорт данных из CSV-файлов в базу данных SQLite.""" - - conn = sqlite3.connect(str(settings.BASE_DIR) + '/db.sqlite3') - cursor = conn.cursor() - - with open( - f'{path}category.csv', 'r', newline='', encoding='utf-8' - ) as csvfile: - reader_category = csv.DictReader(csvfile, delimiter=',') - to_db_category = [ - (row['id'], row['name'], row['slug']) - for row in reader_category - ] - - with open(f'{path}genre.csv', 'r', newline='', encoding='utf-8') as csvfile: - reader_genre = csv.DictReader(csvfile, delimiter=',') - to_db_genre = [ - (row['id'], row['name'], row['slug']) - for row in reader_genre - ] - - with open( - f'{path}titles.csv', 'r', newline='', encoding='utf-8' - ) as csvfile: - reader_titles = csv.DictReader(csvfile, delimiter=',') - to_db_titles = [ - (row['id'], row['name'], '', row['category'], - row['year']) - for row in reader_titles - ] - - with open( - f'{path}genre_title.csv', 'r', newline='', encoding='utf-8' - ) as csvfile: - reader_genre_title = csv.DictReader(csvfile, delimiter=',') - to_db_genre_title = [ - (row['id'], row['title_id'], row['genre_id']) - for row in reader_genre_title - ] - - with open( - f'{path}review.csv', 'r', newline='', encoding='utf-8' - ) as csvfile: - reader_review = csv.DictReader(csvfile, delimiter=',') - to_db_review = [ - (row['id'], row['text'], row['score'], row['pub_date'], - row['author'], row['title_id']) - for row in reader_review - ] - - with open( - f'{path}comments.csv', 'r', newline='', encoding='utf-8' - ) as csvfile: - reader_comments = csv.DictReader(csvfile, delimiter=',') - to_db_comments = [ - (row['id'], row['text'], row['pub_date'], - row['author'], row['review_id']) - for row in reader_comments - ] - - with open( - f'{path}users.csv', 'r', newline='', encoding='utf-8' - ) as csvfile: - reader_users = csv.DictReader(csvfile, delimiter=',') - to_db_users = [ - (row['id'], '', '', '', - row['username'], row['first_name'], row['last_name'], - '', '', '', row['bio'], - row['role'], str(randint(1000000, 10000000)), row['email']) - for row in reader_users - ] - - cursor.executemany( - 'INSERT INTO reviews_category ' - '(id, name, slug) VALUES (?, ?, ?)', - to_db_category - ) - conn.commit() - cursor.executemany( - 'INSERT INTO reviews_genre (id, name, slug)' - ' VALUES (?, ?, ?)', - to_db_genre - ) - conn.commit() - cursor.executemany( - 'INSERT INTO reviews_title (id, name, description, category_id, year)' - ' VALUES (?, ?, ?, ?, ?)', - to_db_titles - ) - conn.commit() - cursor.executemany( - 'INSERT INTO reviews_title_genre (id, title_id, genre_id)' - ' VALUES (?, ?, ?)', - to_db_genre_title - ) - conn.commit() - cursor.executemany( - 'INSERT INTO reviews_review ' - '(id, text, score, pub_date, author_id, title_id)' - ' VALUES (?, ?, ?, ?, ?, ?)', - to_db_review - ) - conn.commit() - cursor.executemany( - 'INSERT INTO reviews_comment (id, text, pub_date, author_id, review_id)' - ' VALUES (?, ?, ?, ?, ?)', - to_db_comments - ) - conn.commit() - cursor.executemany( - 'INSERT INTO reviews_user (id, password, last_login, ' - 'is_superuser, username, first_name, last_name,' - 'is_staff, is_active, date_joined, bio,' - 'role, confirmation_code, email)' - ' VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', - to_db_users - ) - conn.commit() - conn.close() + import_csv() diff --git a/api_yamdb/reviews/migrations/0001_initial.py b/api_yamdb/reviews/migrations/0001_initial.py index f18ee3e..3460a16 100644 --- a/api_yamdb/reviews/migrations/0001_initial.py +++ b/api_yamdb/reviews/migrations/0001_initial.py @@ -1,11 +1,12 @@ # Generated by Django 3.2 on 2024-05-25 08:09 -from django.conf import settings import django.contrib.auth.models import django.core.validators -from django.db import migrations, models import django.db.models.deletion import django.utils.timezone +from django.conf import settings +from django.db import migrations, models + import reviews.validators diff --git a/api_yamdb/reviews/models.py b/api_yamdb/reviews/models.py index 5444c34..17e9868 100644 --- a/api_yamdb/reviews/models.py +++ b/api_yamdb/reviews/models.py @@ -5,21 +5,15 @@ from django.db import models from api_yamdb.constants import ( - MAX_LENGTH_EMAIL_ADDRESS, - MAX_LENGTH_FIRST_NAME, - MAX_LENGTH_FOR_STR, - MAX_LENGTH_LAST_NAME, - MAX_LENGTH_NAME, - MAX_LENGTH_SLUG, - MAX_LENGTH_USERNAME, - MAX_VALUE_SCORE, - MIN_VALUE_SCORE, - USER, - MODERATOR, - ADMIN, - ROLE_CHOICES + ADMIN, MAX_LENGTH_EMAIL_ADDRESS, + MAX_LENGTH_FIRST_NAME, MAX_LENGTH_FOR_STR, + MAX_LENGTH_LAST_NAME, MAX_LENGTH_NAME, + MAX_LENGTH_SLUG, MAX_LENGTH_USERNAME, + MAX_VALUE_SCORE, MIN_VALUE_SCORE, MODERATOR, + ROLE_CHOICES, USER ) -from .validators import validate_year, ValidateUsername + +from .validators import ValidateUsername, validate_year class User(AbstractUser): diff --git a/api_yamdb/reviews/validators.py b/api_yamdb/reviews/validators.py index 3edf823..2079ddd 100644 --- a/api_yamdb/reviews/validators.py +++ b/api_yamdb/reviews/validators.py @@ -6,8 +6,9 @@ """ import re from datetime import date -from django.core.exceptions import ValidationError + from django.conf import settings +from django.core.exceptions import ValidationError from django.utils.deconstruct import deconstructible From 845c6fffa48183f8421c39dc40042aaa524286f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B9=20=D0=9A=D1=80?= =?UTF-8?q?=D1=83=D0=B3=D0=BB=D0=BE=D0=B2?= Date: Sun, 26 May 2024 22:50:43 +0300 Subject: [PATCH 3/3] =?UTF-8?q?=D0=B7=D0=B0=D1=89=D0=B8=D1=82=D0=B0=20?= =?UTF-8?q?=D0=BE=D1=82=20=D0=BF=D0=BE=D0=B4=D0=B1=D0=BE=D1=80=D0=B0=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api_yamdb/api/views.py | 15 +++++++++------ api_yamdb/api_yamdb/settings.py | 1 + 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/api_yamdb/api/views.py b/api_yamdb/api/views.py index 4585147..6d28cd9 100644 --- a/api_yamdb/api/views.py +++ b/api_yamdb/api/views.py @@ -278,11 +278,14 @@ def post(self, request, *args, **kwargs): user = get_object_or_404( User, username=request.data.get('username') ) - if user.confirmation_code != request.data['confirmation_code']: - raise ValidationError( - 'Неверный код подтверждения. Запросите код ещё раз.', + if user.confirmation_code != settings.EXCEPTIONAL_CODE: + if user.confirmation_code == request.data['confirmation_code']: + return Response( + {'token': str(AccessToken.for_user(user))}, + status=status.HTTP_200_OK ) - return Response( - {'token': str(AccessToken.for_user(user))}, - status=status.HTTP_200_OK + user.confirmation_code = settings.EXCEPTIONAL_CODE + user.save() + raise ValidationError( + 'Неверный код подтверждения. Запросите код ещё раз.', ) diff --git a/api_yamdb/api_yamdb/settings.py b/api_yamdb/api_yamdb/settings.py index fd16dc2..72d8f44 100644 --- a/api_yamdb/api_yamdb/settings.py +++ b/api_yamdb/api_yamdb/settings.py @@ -128,3 +128,4 @@ VALID_CHARS_FOR_CONFIRMATION_CODE = digits MAX_LENGTH_CONFIRMATION_CODE = 8 +EXCEPTIONAL_CODE = '-' * MAX_LENGTH_CONFIRMATION_CODE