HEAD
from django.http import HttpResponse, HttpResponseNotFound
from .models import *
from django.shortcuts import render, redirect
from django.contrib import messages
from .models import CallbackRequest # Импортируем из models, а не forms
from .forms import CallbackForm
from django.utils import timezone
from datetime import timedelta
from .models import PageView, Visitor
from django.db.models import Count
from django.contrib.auth.decorators import login_required, user_passes_test
from django.views.decorators.http import require_GET
menu = [
{'title': "Главная", 'url_name': 'home'},
{'title': "Проекты", 'url_name': 'solution'},
{'title': "Компетенции", 'url_name': 'ability'},
{'title': "Отзывы", 'url_name': 'recall'},
{'title': "Обо мне", 'url_name': 'about'}
]
# === ДОБАВЬТЕ ЭТИ ФУНКЦИИ ЗДЕСЬ ===
def get_client_ip(request):
"""Получаем реальный IP клиента"""
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
return ip
def should_track_request(request):
"""Определяем, нужно ли отслеживать запрос"""
client_ip = get_client_ip(request)
path = request.path
# Игнорируемые пути (Nextcloud специфичные)
nextcloud_paths = [
'/index.php',
'/status.php',
'/cron',
'/remote.php',
'/ocs',
'/apps/',
'/custom_apps/',
]
# Игнорируемые IP (Docker сети)
docker_ips = [
'192.168.64.1',
'192.168.65.1',
'172.17.0.1',
'172.18.0.1',
'172.19.0.1',
]
# Игнорируем статические файлы и админку
if path.startswith('/static/') or path.startswith('/admin/'):
return False
# Не отслеживаем Nextcloud и Docker запросы
if any(path.startswith(p) for p in nextcloud_paths):
return False
if client_ip in docker_ips:
return False
return True
def track_page_view(request):
"""Основная функция отслеживания просмотров"""
if not should_track_request(request):
return
try:
PageView.objects.create(
url=request.path,
ip_address=get_client_ip(request),
user_agent=request.META.get('HTTP_USER_AGENT', '')[:500],
referer=request.META.get('HTTP_REFERER', '')[:500],
)
except Exception as e:
print(f"Error tracking page: {e}")
def track_view(view_func):
"""Декоратор для отслеживания просмотров страниц"""
from functools import wraps
@wraps(view_func)
def _wrapped_view(request, *args, **kwargs):
# Отслеживаем просмотр перед выполнением view
track_page_view(request)
return view_func(request, *args, **kwargs)
return _wrapped_view
@track_view
def index(request):
posts = Home.objects.filter(is_published=True)
context = {
'posts': posts,
'menu': menu,
'title': "Главная страница",
'meta_description': "Профессиональный программист 1С с более чем 10-летним опытом. Разработка, интеграция и оптимизация систем 1С. Закажите консультацию.",
'meta_keywords': "программист 1С, разработка 1С, интеграция 1С, оптимизация 1С, 1С предприятие 8.3",
'form': CallbackForm()
}
return render(request, 'programmer/index.html', context=context)
@track_view
def about(request):
context = {
'menu': menu,
'title': "Обо мне - Программист 1С",
'meta_description': "Николай Сердюк - профессиональный программист 1С с более чем 10-летним опытом. Разработка, интеграция, оптимизация бизнес-процессов.",
'meta_keywords': "программист 1С Николай Сердюк, опыт работы 1С, компетенции 1С, проекты 1С"
}
return render(request, 'programmer/about.html', context=context)
@track_view
def solution(request):
posts = Solution.objects.filter(is_published=True)
context = {
'posts': posts,
'menu': menu,
'title': "Проекты"
}
return render(request, 'programmer/solution.html', context=context)
@track_view
def ability(request):
posts = Competence.objects.filter(is_published=True)
context = {
'posts': posts,
'menu': menu,
'title': "Компетенции"
}
return render(request, 'programmer/competence.html', context=context)
@track_view
def recall(request):
posts = Recall.objects.filter(is_published=True)
context = {
'posts': posts,
'menu': menu,
'title': "Отзывы"
}
return render(request, 'programmer/recall.html', context=context)
def show_post(request, post_id):
return HttpResponse(f"Отображение № {post_id}")
def pageNotFound(request, exception):
return HttpResponseNotFound('
Страница не найдена
')
def callback_request(request):
if request.method == 'POST':
form = CallbackForm(request.POST)
if form.is_valid():
# Сохраняем заявку через форму
form.save()
messages.success(request, '✅ Ваша заявка успешно отправлена! Я свяжусь с вами в ближайшее время.')
return redirect('home')
else:
# Если форма невалидна, показываем ошибки
for field, errors in form.errors.items():
for error in errors:
messages.error(request, f'❌ Ошибка в поле {form.fields[field].label}: {error}')
return redirect('home')
# Если GET запрос, просто показываем главную страницу
return redirect('home')
def is_admin(user):
return user.is_staff
def is_staff(user):
return user.is_staff
@login_required
@user_passes_test(is_staff)
def statistics_view(request):
today = timezone.now().date()
week_ago = today - timedelta(days=7)
# Статистика за сегодня
today_views = PageView.objects.filter(
timestamp__date=today
).count()
# Статистика за неделю
weekly_views = PageView.objects.filter(
timestamp__date__gte=week_ago
).count()
# Всего просмотров
total_views = PageView.objects.count()
# Популярные страницы за неделю
popular_pages = PageView.objects.filter(
timestamp__date__gte=week_ago
).values('url').annotate(
views=Count('id')
).order_by('-views')[:10]
# Уникальные посетители за неделю
unique_visitors = Visitor.objects.filter(
last_visit__date__gte=week_ago
).count()
# Последние посещения
recent_views = PageView.objects.select_related().order_by('-timestamp')[:20]
today = timezone.now().date()
total_callbacks = CallbackRequest.objects.count()
today_callbacks = CallbackRequest.objects.filter(time_create__date=today).count()
unread_callbacks = CallbackRequest.objects.filter(is_read=False).count()
context = {
'today_views': today_views,
'weekly_views': weekly_views,
'total_views': total_views,
'unique_visitors': unique_visitors,
'popular_pages': popular_pages,
'recent_views': recent_views,
'total_callbacks': total_callbacks,
'today_callbacks': today_callbacks,
'unread_callbacks': unread_callbacks,
}
return render(request, 'admin/statistics.html', context)
@require_GET
def robots_txt(request):
return render(request, 'robots.txt', content_type='text/plain')
=======
from django.http import HttpResponse, HttpResponseNotFound
from .models import *
from django.shortcuts import render, redirect
from django.contrib import messages
from .models import CallbackRequest # Импортируем из models, а не forms
from .forms import CallbackForm
from django.utils import timezone
from datetime import timedelta
from .models import PageView, Visitor
from django.db.models import Count
from django.contrib.auth.decorators import login_required, user_passes_test
from django.views.decorators.http import require_GET
menu = [
{'title': "Главная", 'url_name': 'home'},
{'title': "Проекты", 'url_name': 'solution'},
{'title': "Компетенции", 'url_name': 'ability'},
{'title': "Отзывы", 'url_name': 'recall'},
{'title': "Обо мне", 'url_name': 'about'}
]
# === ДОБАВЬТЕ ЭТИ ФУНКЦИИ ЗДЕСЬ ===
def get_client_ip(request):
"""Получаем реальный IP клиента"""
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
return ip
def should_track_request(request):
"""Определяем, нужно ли отслеживать запрос"""
client_ip = get_client_ip(request)
path = request.path
# Игнорируемые пути (Nextcloud специфичные)
nextcloud_paths = [
'/index.php',
'/status.php',
'/cron',
'/remote.php',
'/ocs',
'/apps/',
'/custom_apps/',
]
# Игнорируемые IP (Docker сети)
docker_ips = [
'192.168.64.1',
'192.168.65.1',
'172.17.0.1',
'172.18.0.1',
'172.19.0.1',
]
# Игнорируем статические файлы и админку
if path.startswith('/static/') or path.startswith('/admin/'):
return False
# Не отслеживаем Nextcloud и Docker запросы
if any(path.startswith(p) for p in nextcloud_paths):
return False
if client_ip in docker_ips:
return False
return True
def track_page_view(request):
"""Основная функция отслеживания просмотров"""
if not should_track_request(request):
return
try:
PageView.objects.create(
url=request.path,
ip_address=get_client_ip(request),
user_agent=request.META.get('HTTP_USER_AGENT', '')[:500],
referer=request.META.get('HTTP_REFERER', '')[:500],
)
except Exception as e:
print(f"Error tracking page: {e}")
def track_view(view_func):
"""Декоратор для отслеживания просмотров страниц"""
from functools import wraps
@wraps(view_func)
def _wrapped_view(request, *args, **kwargs):
# Отслеживаем просмотр перед выполнением view
track_page_view(request)
return view_func(request, *args, **kwargs)
return _wrapped_view
@track_view
def index(request):
posts = Home.objects.filter(is_published=True)
context = {
'posts': posts,
'menu': menu,
'title': "Программист 1С Николай Сердюк - разработка и сопровождение",
'meta_description': "Профессиональный программист 1С с более чем 10-летним опытом. Разработка, доработка, обновление и интеграция систем 1С. Сопровождение 1С.",
'meta_keywords': "программист 1С, разработка 1С, обновление 1С, сопровождение 1С, интеграция 1С, доработка 1С, 1С предприятие 8.3",
'form': CallbackForm()
}
return render(request, 'programmer/index.html', context=context)
@track_view
def about(request):
context = {
'menu': menu,
'title': "Программист 1С Николай Сердюк - 10+ лет опыта | Услуги 1С",
'meta_description': "Николай Сердюк - сертифицированный программист 1С с 10+ лет опыта. Специализация: обновление 1С, разработка под ключ, интеграция, миграция с 1С 7.7.",
'meta_keywords': "программист 1С Николай Сердюк, обновление 1С, разработка 1С под ключ, интеграция 1С, сертифицированный 1С, миграция 1С 7.7"
}
return render(request, 'programmer/about.html', context=context)
@track_view
def solution(request):
posts = Solution.objects.filter(is_published=True)
context = {
'posts': posts,
'menu': menu,
'meta_description': "Реализованные проекты по автоматизации 1С: складской учет с ТСД, интеграция с оборудованием, миграция с 1С 7.7. Примеры работ и кейсы.",
'meta_keywords': "проекты 1С, автоматизация склада 1С, интеграция ТСД 1С, миграция 1С 7.7, кейсы 1С, примеры работ 1С",
'title': "Проекты автоматизации 1С | Реализованные кейсы и решения",
}
return render(request, 'programmer/solution.html', context=context)
@track_view
def ability(request):
posts = Competence.objects.filter(is_published=True)
context = {
'posts': posts,
'menu': menu,
'title': "Сертификаты и компетенции 1С | Программист 1С Николай Сердюк",
'meta_description': "Сертификаты 1С: Профессионал по платформе 8.3 и БП 3.0. Подтвержденная квалификация программиста 1С с сертификатами фирмы 1С.",
'meta_keywords': "сертификаты 1С, 1С профессионал, компетенции 1С, квалификация программиста 1С, сертифицированный специалист 1С"
}
return render(request, 'programmer/competence.html', context=context)
@track_view
def recall(request):
posts = Recall.objects.filter(is_published=True)
context = {
'posts': posts,
'menu': menu,
'title': "Отзывы клиентов о работе программиста 1С | Реальные кейсы",
'meta_description': "Реальные отзывы клиентов о работе программиста 1С Николая Сердюка. Отзывы от ООО «РОВЕН-Регионы» и других компаний.",
'meta_keywords': "отзывы программист 1С, рекомендации 1С, отзывы клиентов 1С, реальные кейсы 1С, отзыв ООО РОВЕН"
}
return render(request, 'programmer/recall.html', context=context)
def show_post(request, post_id):
return HttpResponse(f"Отображение № {post_id}")
def pageNotFound(request, exception):
return HttpResponseNotFound('Страница не найдена
')
def callback_request(request):
if request.method == 'POST':
form = CallbackForm(request.POST)
if form.is_valid():
# Сохраняем заявку через форму
form.save()
messages.success(request, '✅ Ваша заявка успешно отправлена! Я свяжусь с вами в ближайшее время.')
return redirect('home')
else:
# Если форма невалидна, показываем ошибки
for field, errors in form.errors.items():
for error in errors:
messages.error(request, f'❌ Ошибка в поле {form.fields[field].label}: {error}')
return redirect('home')
# Если GET запрос, просто показываем главную страницу
return redirect('home')
def is_admin(user):
return user.is_staff
def is_staff(user):
return user.is_staff
@login_required
@user_passes_test(is_staff)
def statistics_view(request):
today = timezone.now().date()
week_ago = today - timedelta(days=7)
# Статистика за сегодня
today_views = PageView.objects.filter(
timestamp__date=today
).count()
# Статистика за неделю
weekly_views = PageView.objects.filter(
timestamp__date__gte=week_ago
).count()
# Всего просмотров
total_views = PageView.objects.count()
# Популярные страницы за неделю
popular_pages = PageView.objects.filter(
timestamp__date__gte=week_ago
).values('url').annotate(
views=Count('id')
).order_by('-views')[:10]
# Уникальные посетители за неделю
unique_visitors = Visitor.objects.filter(
last_visit__date__gte=week_ago
).count()
# Последние посещения
recent_views = PageView.objects.select_related().order_by('-timestamp')[:20]
today = timezone.now().date()
total_callbacks = CallbackRequest.objects.count()
today_callbacks = CallbackRequest.objects.filter(time_create__date=today).count()
unread_callbacks = CallbackRequest.objects.filter(is_read=False).count()
context = {
'today_views': today_views,
'weekly_views': weekly_views,
'total_views': total_views,
'unique_visitors': unique_visitors,
'popular_pages': popular_pages,
'recent_views': recent_views,
'total_callbacks': total_callbacks,
'today_callbacks': today_callbacks,
'unread_callbacks': unread_callbacks,
}
return render(request, 'admin/statistics.html', context)
@require_GET
def robots_txt(request):
return render(request, 'robots.txt', content_type='text/plain')
>>>>>>> master