🔧 FIX: Исправлен URL pattern 'about_view' → 'about' + Динамический фильтр категорий услуг из БД
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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')
|
||||||
|
|||||||
Reference in New Issue
Block a user