feat: implement role-based permissions for product views
- Add view mixins (RoleRequiredMixin, OwnerRequiredMixin, ManagerOwnerRequiredMixin) to user_roles/mixins.py - Replace PermissionRequiredMixin with ManagerOwnerRequiredMixin in all product views - Remove permission_required attributes from view classes - Owner and Manager roles now grant access without Django model permissions This allows owners to access all product functionality through their custom role, without needing to be superusers or have explicit Django permissions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
CRUD представления для товаров (Product).
|
||||
"""
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.views.generic import ListView, CreateView, DetailView, UpdateView, DeleteView
|
||||
from django.urls import reverse_lazy
|
||||
from django.db.models import Q, Sum, Value, DecimalField
|
||||
@@ -13,13 +13,13 @@ from ..models import Product, ProductCategory, ProductTag, ProductKit
|
||||
from ..forms import ProductForm
|
||||
from .utils import handle_photos
|
||||
from ..models import ProductPhoto
|
||||
from user_roles.mixins import ManagerOwnerRequiredMixin
|
||||
|
||||
|
||||
class ProductListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
||||
class ProductListView(LoginRequiredMixin, ManagerOwnerRequiredMixin, ListView):
|
||||
model = Product
|
||||
template_name = 'products/product_list.html'
|
||||
context_object_name = 'products'
|
||||
permission_required = 'products.view_product'
|
||||
paginate_by = 10
|
||||
|
||||
def get_queryset(self):
|
||||
@@ -109,11 +109,10 @@ class ProductListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
||||
return context
|
||||
|
||||
|
||||
class ProductCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
|
||||
class ProductCreateView(LoginRequiredMixin, ManagerOwnerRequiredMixin, CreateView):
|
||||
model = Product
|
||||
form_class = ProductForm
|
||||
template_name = 'products/product_form.html'
|
||||
permission_required = 'products.add_product'
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse_lazy('products:products-list')
|
||||
@@ -156,11 +155,10 @@ class ProductCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView)
|
||||
return self.form_invalid(form)
|
||||
|
||||
|
||||
class ProductDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
|
||||
class ProductDetailView(LoginRequiredMixin, ManagerOwnerRequiredMixin, DetailView):
|
||||
model = Product
|
||||
template_name = 'products/product_detail.html'
|
||||
context_object_name = 'product'
|
||||
permission_required = 'products.view_product'
|
||||
|
||||
def get_queryset(self):
|
||||
# Предзагрузка фотографий и аннотация остатков
|
||||
@@ -180,11 +178,10 @@ class ProductDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView)
|
||||
return context
|
||||
|
||||
|
||||
class ProductUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
|
||||
class ProductUpdateView(LoginRequiredMixin, ManagerOwnerRequiredMixin, UpdateView):
|
||||
model = Product
|
||||
form_class = ProductForm
|
||||
template_name = 'products/product_form.html'
|
||||
permission_required = 'products.change_product'
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse_lazy('products:products-list')
|
||||
@@ -234,25 +231,23 @@ class ProductUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView)
|
||||
return self.form_invalid(form)
|
||||
|
||||
|
||||
class ProductDeleteView(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
|
||||
class ProductDeleteView(LoginRequiredMixin, ManagerOwnerRequiredMixin, DeleteView):
|
||||
model = Product
|
||||
template_name = 'products/product_confirm_delete.html'
|
||||
context_object_name = 'product'
|
||||
permission_required = 'products.delete_product'
|
||||
|
||||
def get_success_url(self):
|
||||
messages.success(self.request, f'Товар "{self.object.name}" успешно удален!')
|
||||
return reverse_lazy('products:products-list')
|
||||
|
||||
|
||||
class CombinedProductListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
||||
class CombinedProductListView(LoginRequiredMixin, ManagerOwnerRequiredMixin, ListView):
|
||||
"""
|
||||
Объединенное представление для товаров и комплектов.
|
||||
Показывает оба типа продуктов в одном списке с возможностью фильтрации по типу.
|
||||
"""
|
||||
template_name = 'products/products_list.html'
|
||||
context_object_name = 'items'
|
||||
permission_required = 'products.view_product'
|
||||
paginate_by = 20
|
||||
|
||||
def get_queryset(self):
|
||||
|
||||
Reference in New Issue
Block a user