Compare commits
25 Commits
d8047fdf21
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d322ed5435 | ||
|
|
1e6ae586fc | ||
|
|
1dff9fbffb | ||
|
|
fa14cb808e | ||
|
|
d39ccb46f5 | ||
|
|
507bfe486a | ||
|
|
ca01d60be4 | ||
|
|
dc656e7fe5 | ||
|
|
b32627ab4d | ||
|
|
33e7ebe0a2 | ||
|
|
39dddf2a08 | ||
|
|
8c576b2f2c | ||
|
|
ed3d1b9d13 | ||
|
|
2d3cfe4736 | ||
|
|
aa62fd32c2 | ||
|
|
511d0e7a8c | ||
|
|
8c36b6da9c | ||
|
|
f3577b0128 | ||
|
|
6b68df95dc | ||
|
|
1c4f1814e9 | ||
|
|
7d99a2681d | ||
|
|
bf1cc9b437 | ||
|
|
71b3928b16 | ||
|
|
87c0193990 | ||
|
|
2d86363615 |
2
1.py
2
1.py
@@ -1,5 +1,5 @@
|
|||||||
from pymongo import MongoClient
|
from pymongo import MongoClient
|
||||||
|
#wdq
|
||||||
|
|
||||||
def clean_tags_in_database():
|
def clean_tags_in_database():
|
||||||
client = MongoClient('mongodb://localhost:27017/')
|
client = MongoClient('mongodb://localhost:27017/')
|
||||||
|
|||||||
@@ -1,16 +1,8 @@
|
|||||||
"""
|
|
||||||
Django settings for DJ_Hentai_manga project.
|
|
||||||
|
|
||||||
Generated by 'django-admin startproject' using Django 5.1.7.
|
|
||||||
|
|
||||||
For more information on this file, see
|
|
||||||
https://docs.djangoproject.com/en/5.1/topics/settings/
|
|
||||||
|
|
||||||
For the full list of settings and their values, see
|
|
||||||
https://docs.djangoproject.com/en/5.1/ref/settings/
|
|
||||||
"""
|
|
||||||
from os import path
|
from os import path
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import os
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
load_dotenv() # загружает .env
|
||||||
|
|
||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
@@ -50,6 +42,11 @@ MIDDLEWARE = [
|
|||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ROOT_URLCONF = 'DJ_Hentai_manga.urls'
|
ROOT_URLCONF = 'DJ_Hentai_manga.urls'
|
||||||
|
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
@@ -107,6 +104,7 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||||||
|
|
||||||
LANGUAGE_CODE = 'en-us'
|
LANGUAGE_CODE = 'en-us'
|
||||||
|
|
||||||
|
|
||||||
TIME_ZONE = 'UTC'
|
TIME_ZONE = 'UTC'
|
||||||
|
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
@@ -119,11 +117,15 @@ USE_TZ = True
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
STATIC_URL = '/templates/static/'
|
STATIC_URL = '/static/'
|
||||||
|
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
|
||||||
|
|
||||||
# Указываем Django искать статику в вашей папке templates/static
|
MEDIA_URL = '/media/'
|
||||||
|
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
|
||||||
|
|
||||||
|
# Указываем Django искать статику в вашей папке /static
|
||||||
STATICFILES_DIRS = [
|
STATICFILES_DIRS = [
|
||||||
os.path.join(BASE_DIR, 'templates/static'),
|
os.path.join(BASE_DIR, 'static'),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Default primary key field type
|
# Default primary key field type
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ https://docs.djangoproject.com/en/5.1/howto/deployment/wsgi/
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from django.core.wsgi import get_wsgi_application
|
from django.core.wsgi import get_wsgi_application
|
||||||
|
from django.contrib.staticfiles.handlers import StaticFilesHandler
|
||||||
|
|
||||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'DJ_Hentai_manga.settings')
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'DJ_Hentai_manga.settings')
|
||||||
|
|
||||||
application = get_wsgi_application()
|
application = StaticFilesHandler(get_wsgi_application())
|
||||||
|
|
||||||
|
|||||||
0
Hentai_manga_model/__init__.py
Normal file
0
Hentai_manga_model/__init__.py
Normal file
0
Hentai_manga_model/migrations/__init__.py
Normal file
0
Hentai_manga_model/migrations/__init__.py
Normal file
@@ -1,10 +1,18 @@
|
|||||||
|
import os
|
||||||
from pymongo import MongoClient
|
from pymongo import MongoClient
|
||||||
|
|
||||||
client = MongoClient('mongodb://localhost:27017/')
|
# Получаем URI только из переменной окружения — НИКАКОГО DEFAULT!
|
||||||
db = client['Manga'] # Название базы данных
|
MONGO_URI = os.getenv("MONGO_URI")
|
||||||
manga_collection = db['Hentai_Manga'] # Название коллекции
|
if not MONGO_URI:
|
||||||
|
raise RuntimeError("Ошибка: переменная окружения MONGO_URI не задана!")
|
||||||
|
|
||||||
|
# Подключаемся
|
||||||
|
client = MongoClient(MONGO_URI)
|
||||||
|
|
||||||
|
# База данных и коллекция берутся из URI!
|
||||||
|
# Например: mongodb://.../Manga → база = Manga
|
||||||
|
db = client.get_database() # ← автоматически из URI
|
||||||
|
manga_collection = db["Hentai_manga"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,36 +1,70 @@
|
|||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.core.paginator import Paginator
|
from django.core.paginator import Paginator
|
||||||
|
from django.core.cache import cache
|
||||||
from .models import manga_collection
|
from .models import manga_collection
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
|
||||||
def manga_catalog(request):
|
def manga_catalog(request):
|
||||||
# Получаем список всех уникальных тегов
|
# Кешируем общее количество (раз в 5 минут)
|
||||||
|
total_manga_count = cache.get('total_manga_count')
|
||||||
|
if total_manga_count is None:
|
||||||
|
total_manga_count = manga_collection.estimated_document_count()
|
||||||
|
cache.set('total_manga_count', total_manga_count, 300)
|
||||||
|
|
||||||
|
# Все теги — можно тоже кешировать, но пока оставим
|
||||||
all_tags = manga_collection.distinct("tags")
|
all_tags = manga_collection.distinct("tags")
|
||||||
|
|
||||||
# Получаем выбранные теги из GET-параметров
|
# Получаем выбранные теги
|
||||||
selected_tags = request.GET.getlist('tags')
|
selected_tags = request.GET.getlist('tags')
|
||||||
|
|
||||||
# Формируем запрос для фильтрации
|
|
||||||
query = {}
|
query = {}
|
||||||
if selected_tags:
|
if selected_tags:
|
||||||
query['tags'] = {'$all': selected_tags}
|
query['tags'] = {'$all': selected_tags}
|
||||||
|
|
||||||
# Получаем отфильтрованные записи
|
query_key = hashlib.md5(str(query).encode()).hexdigest()
|
||||||
filtered_manga = list(manga_collection.find(query))
|
cache_key = f"count_{query_key}"
|
||||||
|
total_filtered = cache.get(cache_key)
|
||||||
|
|
||||||
# Пагинация
|
if total_filtered is None:
|
||||||
paginator = Paginator(filtered_manga, 20)
|
total_filtered = manga_collection.count_documents(query)
|
||||||
page_number = request.GET.get('page')
|
cache.set(cache_key, total_filtered, 60) # на 1 минуту
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
""" query = {}
|
||||||
|
if selected_tags:
|
||||||
|
query['tags'] = {'$all': selected_tags}
|
||||||
|
|
||||||
|
# Считаем количество для пагинации (можно тоже кешировать по хешу, но пока так)
|
||||||
|
total_filtered = manga_collection.count_documents(query)"""
|
||||||
|
|
||||||
|
# Получаем номер страницы
|
||||||
|
page_number = request.GET.get('page') or 1
|
||||||
|
try:
|
||||||
|
page_number = int(page_number)
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
page_number = 1
|
||||||
|
|
||||||
|
per_page = 20
|
||||||
|
skip = (page_number - 1) * per_page
|
||||||
|
|
||||||
|
# Получаем только текущую страницу
|
||||||
|
manga_cursor = manga_collection.find(query).skip(skip).limit(per_page)
|
||||||
|
manga_list = list(manga_cursor)
|
||||||
|
|
||||||
|
# Создаём Paginator и page_obj ПРАВИЛЬНО
|
||||||
|
paginator = Paginator(range(total_filtered), per_page)
|
||||||
page_obj = paginator.get_page(page_number)
|
page_obj = paginator.get_page(page_number)
|
||||||
|
|
||||||
total_manga_count = manga_collection.count_documents({})
|
# Передаём данные в шаблон
|
||||||
|
|
||||||
return render(request, 'manga_catalog.html', {
|
return render(request, 'manga_catalog.html', {
|
||||||
'page_obj': page_obj,
|
'page_obj': page_obj,
|
||||||
'manga_list': page_obj.object_list,
|
'manga_list': manga_list,
|
||||||
'total_manga_count': total_manga_count,
|
'total_manga_count': total_manga_count,
|
||||||
'all_tags': sorted(all_tags),
|
'all_tags': sorted(all_tags),
|
||||||
'selected_tags': selected_tags
|
'selected_tags': selected_tags,
|
||||||
})
|
})
|
||||||
|
|
||||||
def show_manga(request, manga_id):
|
def show_manga(request, manga_id):
|
||||||
|
|||||||
BIN
requirements.txt
Normal file
BIN
requirements.txt
Normal file
Binary file not shown.
0
static/js/Manga_catalog.js
Normal file
0
static/js/Manga_catalog.js
Normal file
10
templates/not_found.html
Normal file
10
templates/not_found.html
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Title</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user