🔧 FIX: Исправлен URL pattern 'about_view' → 'about' + Динамический фильтр категорий услуг из БД
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2025-11-25 13:06:48 +09:00
parent 9c3a932386
commit 975bc4ee61
3 changed files with 28 additions and 53 deletions

View File

@@ -7,7 +7,7 @@
<div id="navcol-5" class="collapse navbar-collapse"> <div id="navcol-5" class="collapse navbar-collapse">
<ul class="navbar-nav ms-auto"> <ul class="navbar-nav ms-auto">
<li class="nav-item"><a class="nav-link active" href="{% url 'services' %}">Услуги</a></li> <li class="nav-item"><a class="nav-link active" href="{% url 'services' %}">Услуги</a></li>
<li class="nav-item"><a class="nav-link" href="{% url 'about_view' %}">О нас</a></li> <li class="nav-item"><a class="nav-link" href="{% url 'about' %}">О нас</a></li>
</ul> </ul>
</div> </div>
</div> </div>

View File

@@ -27,28 +27,21 @@
<div class="container-modern"> <div class="container-modern">
<!-- Service Categories Filter --> <!-- Service Categories Filter -->
<div class="text-center mb-5"> <div class="text-center mb-5">
<div class="btn-group" role="group" aria-label="Категории услуг"> <div class="btn-group flex-wrap justify-content-center" role="group" aria-label="Категории услуг">
<button type="button" class="btn btn-outline-primary active" data-filter="all"> <a href="?category=all" class="btn btn-outline-primary {% if selected_category == 'all' %}active{% endif %} mb-2">
Все услуги Все услуги
</button> </a>
<button type="button" class="btn btn-outline-primary" data-filter="web"> {% for category in categories %}
Веб-разработка <a href="?category={{ category.name|lower }}" class="btn btn-outline-primary {% if selected_category == category.name|lower %}active{% endif %} mb-2">
</button> {{ category.name }}
<button type="button" class="btn btn-outline-primary" data-filter="mobile"> </a>
Мобильные приложения {% endfor %}
</button>
<button type="button" class="btn btn-outline-primary" data-filter="design">
Дизайн
</button>
<button type="button" class="btn btn-outline-primary" data-filter="other">
Другое
</button>
</div> </div>
</div> </div>
<div class="row g-4" id="services-container"> <div class="row g-4" id="services-container">
{% for service in services %} {% for service in services %}
<div class="col-lg-4 col-md-6 service-item" data-category="{{ service.category.name|lower }}"> <div class="col-lg-4 col-md-6 service-item">
<div class="card-modern h-100"> <div class="card-modern h-100">
<div class="position-relative overflow-hidden" style="height: 200px;"> <div class="position-relative overflow-hidden" style="height: 200px;">
{% if service.video %} {% if service.video %}
@@ -383,39 +376,6 @@
{% block extra_scripts %} {% block extra_scripts %}
<script> <script>
// Service filtering
document.addEventListener('DOMContentLoaded', function() {
const filterButtons = document.querySelectorAll('[data-filter]');
const serviceItems = document.querySelectorAll('.service-item');
filterButtons.forEach(button => {
button.addEventListener('click', function() {
const filter = this.getAttribute('data-filter');
// Update active button
filterButtons.forEach(btn => btn.classList.remove('active'));
this.classList.add('active');
// Filter services
serviceItems.forEach(item => {
if (filter === 'all' || item.getAttribute('data-category').includes(filter)) {
item.style.display = 'block';
setTimeout(() => {
item.style.opacity = '1';
item.style.transform = 'translateY(0)';
}, 50);
} else {
item.style.opacity = '0';
item.style.transform = 'translateY(20px)';
setTimeout(() => {
item.style.display = 'none';
}, 300);
}
});
});
});
});
// Service modal // Service modal
function openServiceModal(serviceId, serviceName) { function openServiceModal(serviceId, serviceName) {
document.getElementById('serviceId').value = serviceId; document.getElementById('serviceId').value = serviceId;

View File

@@ -1,5 +1,5 @@
from django.shortcuts import render, get_object_or_404, redirect from django.shortcuts import render, get_object_or_404, redirect
from .models import Service, Project, Client, BlogPost, Review, Order, ServiceRequest, HeroBanner from .models import Service, Project, Client, BlogPost, Review, Order, ServiceRequest, HeroBanner, Category
from django.db.models import Avg from django.db.models import Avg
from comunication.models import TelegramSettings from comunication.models import TelegramSettings
import qrcode import qrcode
@@ -76,8 +76,23 @@ def blog_post_detail(request, pk):
return render(request, 'web/blog_post_detail.html', {'blog_post': blog_post}) return render(request, 'web/blog_post_detail.html', {'blog_post': blog_post})
def services_view(request): def services_view(request):
services = Service.objects.all() # Получаем выбранную категорию из GET параметра
return render(request, 'web/services_modern.html', {'services': services}) selected_category = request.GET.get('category', 'all')
# Получаем все категории для фильтра
categories = Category.objects.all().order_by('name')
# Фильтруем услуги по категории
if selected_category == 'all' or not selected_category:
services = Service.objects.all().order_by('name')
else:
services = Service.objects.filter(category__name__icontains=selected_category).order_by('name')
return render(request, 'web/services_modern.html', {
'services': services,
'categories': categories,
'selected_category': selected_category
})
def about_view(request): def about_view(request):
return render(request, 'web/about_modern.html') return render(request, 'web/about_modern.html')