django-jqgrid


Namedjango-jqgrid JSON
Version 1.2.7 PyPI version JSON
download
home_pagehttps://github.com/coder-aniket/django-jqgrid
SummaryA Django app for integrating jqGrid with Django REST Framework
upload_time2025-07-22 18:39:38
maintainerNone
docs_urlNone
authorYour Name
requires_python>=3.8
licenseMIT
keywords django jqgrid rest framework grid datatable
VCS
bugtrack_url
requirements Django djangorestframework django-filter
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Django jqGrid Package

A comprehensive Django package that provides seamless integration of jqGrid with Django REST Framework, offering powerful data grid functionality with minimal configuration.

## Features

- **Automatic Configuration**: Generates jqGrid configuration from Django model metadata and DRF serializers
- **Full CRUD Support**: Built-in Create, Read, Update, Delete operations via REST API
- **Advanced Features**:
  - Multi-column sorting
  - Advanced filtering with multiple operators
  - Bulk operations (update/delete)
  - Row grouping and aggregation
  - Frozen columns
  - Conditional formatting
  - Import/Export functionality
  - Custom grid filters per user
- **Responsive Design**: Bootstrap 4/5 compatible with mobile support
- **Security**: Permission-based access control
- **Extensible**: Easy to customize and extend

## Installation

```bash
pip install django-jqgrid
```

## Quick Start

### 1. Add to Installed Apps

```python
INSTALLED_APPS = [
    # ...
    'rest_framework',
    'django_jqgrid',
    # ...
]
```

### 2. Include URLs

```python
# urls.py
from django.urls import path, include

urlpatterns = [
    # ...
    path('api/grid/', include('django_jqgrid.urls')),
    # ...
]
```

### 3. Create a ViewSet with JqGrid Mixin

```python
# views.py
from rest_framework import viewsets
from django_jqgrid.mixins import JqGridConfigMixin, JqGridBulkActionMixin
from .models import YourModel
from .serializers import YourModelSerializer

class YourModelViewSet(JqGridConfigMixin, JqGridBulkActionMixin, viewsets.ModelViewSet):
    queryset = YourModel.objects.all()
    serializer_class = YourModelSerializer
    
    # Optional: Customize visible columns
    visible_columns = ['id', 'name', 'email', 'created_at']
    
    # Optional: Define searchable fields
    search_fields = ['name', 'email']
    
    # Optional: Define sortable fields
    ordering_fields = ['name', 'created_at']
    
    # Optional: Default ordering
    ordering = ['-created_at']
```

### 4. Add jqGrid to Your Template

```html
<!-- Include jQuery and jqGrid files -->
<link rel="stylesheet" href="{% static 'django_jqgrid/plugins/jqGrid/css/ui.jqgrid-bootstrap4.css' %}">
<script src="{% static 'django_jqgrid/plugins/jqGrid/js/jquery.jqGrid.min.js' %}"></script>
<script src="{% static 'django_jqgrid/js/jqgrid-integration.js' %}"></script>

<!-- Grid Container -->
<table id="jqGrid"></table>
<div id="jqGridPager"></div>

<script>
$(document).ready(function() {
    // Initialize jqGrid with configuration from API
    $.getJSON('/api/yourapp/yourmodel/jqgrid_config/', function(config) {
        $("#jqGrid").jqGrid(config.jqgrid_options);
        
        // Apply method options
        $("#jqGrid").jqGrid('navGrid', '#jqGridPager', 
            config.method_options.navGrid.options,
            config.method_options.navGrid.editOptions,
            config.method_options.navGrid.addOptions,
            config.method_options.navGrid.delOptions,
            config.method_options.navGrid.searchOptions,
            config.method_options.navGrid.viewOptions
        );
        
        // Apply filter toolbar
        $("#jqGrid").jqGrid('filterToolbar', config.method_options.filterToolbar.options);
    });
});
</script>
```

## Configuration

### Serializer-Based Configuration

The package automatically configures jqGrid based on your DRF serializer fields:

```python
from rest_framework import serializers
from .models import Product

class ProductSerializer(serializers.ModelSerializer):
    # Read-only fields become non-editable in grid
    total_sales = serializers.ReadOnlyField()
    
    # Custom labels are used in grid headers
    name = serializers.CharField(label="Product Name")
    
    # Field types determine grid column types
    price = serializers.DecimalField(max_digits=10, decimal_places=2)
    in_stock = serializers.BooleanField()
    created_at = serializers.DateTimeField(read_only=True)
    
    class Meta:
        model = Product
        fields = ['id', 'name', 'price', 'in_stock', 'total_sales', 'created_at']
```

### Field Type Mappings

The package automatically maps Django field types to jqGrid column configurations:

| Django Field Type | jqGrid Configuration |
|------------------|---------------------|
| CharField | `stype: 'text'`, search operators: eq, ne, cn, nc, bw, bn, ew, en |
| IntegerField | `stype: 'integer'`, `align: 'right'`, search operators: eq, ne, lt, le, gt, ge |
| DecimalField | `stype: 'number'`, `align: 'right'`, with decimal places |
| BooleanField | `stype: 'checkbox'`, `align: 'center'` |
| DateField | `stype: 'date'`, with datepicker |
| DateTimeField | `stype: 'datetime-local'`, with datetimepicker |
| ForeignKey | `stype: 'select'`, with dropdown data URL |
| EmailField | `stype: 'email'`, `formatter: 'email'` |
| URLField | `stype: 'text'`, `formatter: 'link'` |

### ViewSet Configuration Options

```python
class ProductViewSet(JqGridConfigMixin, JqGridBulkActionMixin, viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    
    # Column visibility
    visible_columns = ['id', 'name', 'price', 'in_stock', 'created_at']
    
    # Search configuration
    search_fields = ['name', 'description', 'sku']
    
    # Sorting configuration
    ordering_fields = ['name', 'price', 'created_at']
    ordering = ['-created_at', 'name']  # Default sort
    
    # Grouping configuration
    groupable_fields = ['category', 'brand']
    
    # Frozen columns (stay visible when scrolling)
    frozen_columns = ['id', 'name']
    
    # Bulk operations
    bulk_updateable_fields = ['price', 'in_stock', 'category']
    bulk_actions = [
        {
            'id': 'bulk-update-price',
            'label': 'Update Price',
            'icon': 'fa-dollar',
            'class': 'btn-warning'
        },
        {
            'id': 'bulk-delete',
            'label': 'Delete Selected',
            'icon': 'fa-trash',
            'class': 'btn-danger'
        }
    ]
    
    # Field overrides
    jqgrid_field_overrides = {
        'price': {
            'formatter': 'currency',
            'formatoptions': {'prefix': '$', 'decimalPlaces': 2}
        }
    }
    
    # Grid options override
    jqgrid_options_override = {
        'rowNum': 50,
        'height': 600,
        'caption': 'Product Inventory'
    }
    
    # Conditional formatting
    conditional_formatting = {
        'in_stock': {
            'false': {'color': 'red', 'background': '#ffeeee'},
            'true': {'color': 'green', 'background': '#eeffee'}
        },
        'price': {
            'condition': 'value > 1000',
            'style': {'fontWeight': 'bold', 'color': 'blue'}
        }
    }
```

## Advanced Features

### 1. Bulk Operations

The `JqGridBulkActionMixin` provides bulk update and delete functionality:

```javascript
// Bulk update example
$.ajax({
    url: '/api/products/bulk_action/',
    method: 'POST',
    data: JSON.stringify({
        ids: [1, 2, 3],
        action: {
            price: 29.99,
            in_stock: true
        }
    }),
    contentType: 'application/json'
});

// Bulk delete example
$.ajax({
    url: '/api/products/bulk_action/',
    method: 'POST',
    data: JSON.stringify({
        ids: [1, 2, 3],
        action: {
            _delete: true
        }
    }),
    contentType: 'application/json'
});
```

### 2. Custom Grid Filters

Users can save and manage custom grid filters:

```python
# The package includes GridFilter model for storing user filters
from django_jqgrid.models import GridFilter

# Filters are automatically available in the grid search dialog
# Users can save search criteria as named filters
```

### 3. Import/Export Configuration

```python
class ProductViewSet(JqGridConfigMixin, viewsets.ModelViewSet):
    # ... other configuration ...
    
    import_config = {
        'supported_formats': ['csv', 'xlsx', 'json'],
        'field_mapping': {
            'Product Name': 'name',
            'Price': 'price',
            'Stock': 'in_stock'
        }
    }
    
    export_config = {
        'formats': ['csv', 'xlsx', 'pdf'],
        'include_headers': True,
        'max_rows': 10000
    }
```

### 4. Row Grouping

```python
class OrderViewSet(JqGridConfigMixin, viewsets.ModelViewSet):
    # ... other configuration ...
    
    groupable_fields = ['status', 'customer', 'date']
    aggregation_fields = {
        'total': 'sum',
        'items_count': 'count'
    }
```

## API Endpoints

The package automatically creates these endpoints for each model:

- `GET /api/<app>/<model>/` - List/search records with jqGrid parameters
- `GET /api/<app>/<model>/jqgrid_config/` - Get grid configuration
- `POST /api/<app>/<model>/crud/` - Handle jqGrid CRUD operations
- `POST /api/<app>/<model>/bulk_action/` - Bulk update/delete
- `GET /api/<app>/<model>/dropdown/` - Get dropdown data for foreign keys

## Settings

```python
# settings.py

# Default grid options (optional)
JQGRID_DEFAULT_GRID_OPTIONS = {
    'rowNum': 25,
    'rowList': [25, 50, 100, 500, 1000],
    'height': 400,
    'styleUI': 'Bootstrap4',
    'iconSet': 'fontAwesome'
}

# Default field type configurations (optional)
JQGRID_DEFAULT_FIELD_CONFIG = {
    'DateField': {
        'formatoptions': {"srcformat": "ISO8601Short", "newformat": "d/m/Y"}
    }
}
```

## JavaScript Integration

The package includes JavaScript utilities for enhanced functionality:

```javascript
// jqgrid-integration.js provides helper functions

// Handle form responses
window.handleFormResponse = function(response, postdata) {
    // Custom response handling
};

// Handle export
window.handleExport = function() {
    // Export grid data
};

// Handle import
window.handleImport = function() {
    // Import data dialog
};
```

## Theme Configuration

Django jqGrid supports multiple themes and can be easily customized to match your application's design.

### Using the Theme Template Tag

```django
{% load jqgrid_tags %}

<!-- Use default theme (Bootstrap 4) -->
{% jqgrid_theme %}

<!-- Specify theme and icon set -->
{% jqgrid_theme 'bootstrap5' 'fontAwesome' %}

<!-- Use custom CSS -->
{% jqgrid_theme theme='bootstrap4' custom_css='/static/css/my-grid-theme.css' %}
```

### Available Themes

- **bootstrap** - Bootstrap 3 theme
- **bootstrap4** - Bootstrap 4 theme (default)
- **bootstrap5** - Bootstrap 5 theme
- **jqueryui** - jQuery UI theme

### Available Icon Sets

- **fontAwesome** - Font Awesome icons (default)
- **bootstrap** - Bootstrap Icons
- **jQueryUI** - jQuery UI icons
- **glyph** - Glyphicons (Bootstrap 3)

### Settings-Based Configuration

Configure theme globally in your Django settings:

```python
# settings.py
JQGRID_THEME = 'bootstrap5'
JQGRID_ICON_SET = 'fontAwesome'
JQGRID_CUSTOM_CSS = '/static/css/custom-grid.css'
```

### Dynamic Theme Switching

Include the theme switcher component:

```html
<!-- Theme switcher container -->
<div id="theme-switcher"></div>

<!-- Include theme switcher JS -->
<script src="{% static 'django_jqgrid/js/jqgrid-theme-switcher.js' %}"></script>

<script>
// Initialize theme switcher
jqGridThemeSwitcher.init({
    container: '#theme-switcher',
    showPreview: true,
    onChange: function(theme, iconSet) {
        console.log('Theme changed to:', theme, iconSet);
    }
});
</script>
```

### Custom Theme CSS

Create your own theme by overriding CSS variables:

```css
/* custom-grid-theme.css */
:root {
    /* Grid colors */
    --jqgrid-header-bg: #2c3e50;
    --jqgrid-header-text: #ffffff;
    --jqgrid-row-hover: #ecf0f1;
    --jqgrid-row-selected: #3498db;
    
    /* Borders */
    --jqgrid-border-color: #bdc3c7;
    
    /* Fonts */
    --jqgrid-font-size: 14px;
    --jqgrid-header-font-weight: 600;
}

/* Dark mode support */
@media (prefers-color-scheme: dark) {
    :root {
        --jqgrid-header-bg: #1a1a1a;
        --jqgrid-row-bg: #2a2a2a;
        --jqgrid-row-alt-bg: #333333;
    }
}
```

## Customization and Extension

Django jqGrid is designed to be highly customizable. Here are some common customization examples:

### Quick Customization Examples

#### 1. Custom Formatters
```javascript
// Register a custom status badge formatter
window.jqGridConfig.formatters.statusBadge = function(cellval, opts) {
    const statusClasses = {
        'active': 'badge-success',
        'pending': 'badge-warning',
        'inactive': 'badge-danger'
    };
    const badgeClass = statusClasses[cellval] || 'badge-info';
    return `<span class="badge ${badgeClass}">${cellval}</span>`;
};

// Use in ViewSet
jqgrid_field_overrides = {
    'status': {
        'formatter': 'statusBadge',
        'align': 'center'
    }
}
```

#### 2. Custom Bulk Actions
```python
class ProductViewSet(JqGridConfigMixin, JqGridBulkActionMixin, viewsets.ModelViewSet):
    # Define custom bulk actions
    bulk_actions = [
        {
            'id': 'apply-discount',
            'label': 'Apply Discount',
            'icon': 'fa-percent',
            'class': 'btn-warning'
        }
    ]
    
    @action(methods=['post'], detail=False)
    def bulk_action(self, request):
        action_id = request.data.get('action_id')
        if action_id == 'apply-discount':
            # Custom logic here
            return Response({'status': 'success'})
        return super().bulk_action(request)
```

#### 3. JavaScript Hooks
```javascript
// Customize grid behavior using hooks
window.jqGridConfig.hooks.beforeInitGrid = function(tableInstance) {
    // Add custom configuration before grid initializes
    tableInstance.options.customData = { department: 'sales' };
};

window.jqGridConfig.hooks.afterSubmitBulkUpdate = function(tableInstance, ids, action, scope, response) {
    // Custom notification after bulk update
    showCustomNotification('Updated ' + ids.length + ' records');
};
```

#### 4. Dynamic Column Configuration
```python
class UserAwareProductViewSet(JqGridConfigMixin, viewsets.ModelViewSet):
    def get_visible_columns(self):
        """Show different columns based on user permissions"""
        base_columns = ['id', 'name', 'price']
        
        if self.request.user.has_perm('products.view_cost'):
            base_columns.extend(['cost', 'profit_margin'])
        
        if self.request.user.is_staff:
            base_columns.extend(['supplier', 'internal_notes'])
        
        return base_columns
    
    def get_jqgrid_config(self, request):
        self.visible_columns = self.get_visible_columns()
        return super().get_jqgrid_config(request)
```

#### 5. Custom Toolbar Buttons
```javascript
// Add custom buttons to specific tables
window.jqGridConfig.customButtons.product = [
    {
        id: 'import-csv',
        label: 'Import CSV',
        icon: 'fa-file-csv',
        class: 'btn-success',
        action: function(tableInstance) {
            showImportModal(tableInstance);
        }
    }
];
```

### Complete Customization Guide

For comprehensive customization examples including:
- Advanced ViewSet customization
- Custom field types
- Theme customization
- Real-time updates
- Performance optimization
- Complex real-world examples

See the [**Customization Guide**](CUSTOMIZATION_GUIDE.md).

## Example Project

The package includes a complete example project demonstrating all features:

### Running the Example Project

```bash
# Navigate to example project
cd example_project

# Install dependencies
pip install -r requirements.txt

# Setup the project
python setup_example.py

# Run the server
python manage.py runserver
```

Visit: `http://localhost:8000/`

## Security

- All operations respect Django's permission system
- CSRF protection for all POST requests
- User-specific filters are isolated
- Bulk operations validate field permissions

## Browser Support

- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
- Mobile browsers (responsive mode)

## Troubleshooting

### Common Issues

#### 1. "jqgrid_tags is not a registered tag library"
**Solution:**
- Ensure `django_jqgrid` is in your `INSTALLED_APPS`
- Restart the Django development server
- If developing locally, install the package in editable mode: `pip install -e .`

#### 2. Grid not loading data
**Solution:**
- Check browser console for JavaScript errors
- Verify the API endpoint is accessible
- Ensure DRF permissions allow access
- Check that the ViewSet URL pattern is correct

#### 3. Bulk operations not working
**Solution:**
- Verify `JqGridBulkActionMixin` is included in your ViewSet
- Check CSRF token is being sent with requests
- Ensure user has appropriate permissions

#### 4. Custom formatters not displaying
**Solution:**
- Register formatters before grid initialization
- Check formatter function name matches configuration
- Verify no JavaScript errors in formatter function

#### 5. Performance issues with large datasets
**Solution:**
- Use server-side pagination (enabled by default)
- Add database indexes on frequently sorted/filtered columns
- Use `select_related()` and `prefetch_related()` in querysets
- Consider implementing caching for frequently accessed data

For more detailed troubleshooting, see the [Customization Guide](CUSTOMIZATION_GUIDE.md#troubleshooting).

## Requirements

- Python 3.8+
- Django 3.2+
- Django REST Framework 3.12+

## License

This project is licensed under the MIT License - see the LICENSE file for details.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Support

For issues and feature requests, please use the [GitHub issue tracker](https://github.com/coder-aniket/django-jqgrid/issues).

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/coder-aniket/django-jqgrid",
    "name": "django-jqgrid",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "django, jqgrid, rest, framework, grid, datatable",
    "author": "Your Name",
    "author_email": "Django jqGrid Team <support@django-jqgrid.org>",
    "download_url": "https://files.pythonhosted.org/packages/c4/62/c5d408e16d4d70e92795c08f8196bbf891b520bc7aeef1d8b58a3ac5ee8d/django_jqgrid-1.2.7.tar.gz",
    "platform": null,
    "description": "# Django jqGrid Package\r\n\r\nA comprehensive Django package that provides seamless integration of jqGrid with Django REST Framework, offering powerful data grid functionality with minimal configuration.\r\n\r\n## Features\r\n\r\n- **Automatic Configuration**: Generates jqGrid configuration from Django model metadata and DRF serializers\r\n- **Full CRUD Support**: Built-in Create, Read, Update, Delete operations via REST API\r\n- **Advanced Features**:\r\n  - Multi-column sorting\r\n  - Advanced filtering with multiple operators\r\n  - Bulk operations (update/delete)\r\n  - Row grouping and aggregation\r\n  - Frozen columns\r\n  - Conditional formatting\r\n  - Import/Export functionality\r\n  - Custom grid filters per user\r\n- **Responsive Design**: Bootstrap 4/5 compatible with mobile support\r\n- **Security**: Permission-based access control\r\n- **Extensible**: Easy to customize and extend\r\n\r\n## Installation\r\n\r\n```bash\r\npip install django-jqgrid\r\n```\r\n\r\n## Quick Start\r\n\r\n### 1. Add to Installed Apps\r\n\r\n```python\r\nINSTALLED_APPS = [\r\n    # ...\r\n    'rest_framework',\r\n    'django_jqgrid',\r\n    # ...\r\n]\r\n```\r\n\r\n### 2. Include URLs\r\n\r\n```python\r\n# urls.py\r\nfrom django.urls import path, include\r\n\r\nurlpatterns = [\r\n    # ...\r\n    path('api/grid/', include('django_jqgrid.urls')),\r\n    # ...\r\n]\r\n```\r\n\r\n### 3. Create a ViewSet with JqGrid Mixin\r\n\r\n```python\r\n# views.py\r\nfrom rest_framework import viewsets\r\nfrom django_jqgrid.mixins import JqGridConfigMixin, JqGridBulkActionMixin\r\nfrom .models import YourModel\r\nfrom .serializers import YourModelSerializer\r\n\r\nclass YourModelViewSet(JqGridConfigMixin, JqGridBulkActionMixin, viewsets.ModelViewSet):\r\n    queryset = YourModel.objects.all()\r\n    serializer_class = YourModelSerializer\r\n    \r\n    # Optional: Customize visible columns\r\n    visible_columns = ['id', 'name', 'email', 'created_at']\r\n    \r\n    # Optional: Define searchable fields\r\n    search_fields = ['name', 'email']\r\n    \r\n    # Optional: Define sortable fields\r\n    ordering_fields = ['name', 'created_at']\r\n    \r\n    # Optional: Default ordering\r\n    ordering = ['-created_at']\r\n```\r\n\r\n### 4. Add jqGrid to Your Template\r\n\r\n```html\r\n<!-- Include jQuery and jqGrid files -->\r\n<link rel=\"stylesheet\" href=\"{% static 'django_jqgrid/plugins/jqGrid/css/ui.jqgrid-bootstrap4.css' %}\">\r\n<script src=\"{% static 'django_jqgrid/plugins/jqGrid/js/jquery.jqGrid.min.js' %}\"></script>\r\n<script src=\"{% static 'django_jqgrid/js/jqgrid-integration.js' %}\"></script>\r\n\r\n<!-- Grid Container -->\r\n<table id=\"jqGrid\"></table>\r\n<div id=\"jqGridPager\"></div>\r\n\r\n<script>\r\n$(document).ready(function() {\r\n    // Initialize jqGrid with configuration from API\r\n    $.getJSON('/api/yourapp/yourmodel/jqgrid_config/', function(config) {\r\n        $(\"#jqGrid\").jqGrid(config.jqgrid_options);\r\n        \r\n        // Apply method options\r\n        $(\"#jqGrid\").jqGrid('navGrid', '#jqGridPager', \r\n            config.method_options.navGrid.options,\r\n            config.method_options.navGrid.editOptions,\r\n            config.method_options.navGrid.addOptions,\r\n            config.method_options.navGrid.delOptions,\r\n            config.method_options.navGrid.searchOptions,\r\n            config.method_options.navGrid.viewOptions\r\n        );\r\n        \r\n        // Apply filter toolbar\r\n        $(\"#jqGrid\").jqGrid('filterToolbar', config.method_options.filterToolbar.options);\r\n    });\r\n});\r\n</script>\r\n```\r\n\r\n## Configuration\r\n\r\n### Serializer-Based Configuration\r\n\r\nThe package automatically configures jqGrid based on your DRF serializer fields:\r\n\r\n```python\r\nfrom rest_framework import serializers\r\nfrom .models import Product\r\n\r\nclass ProductSerializer(serializers.ModelSerializer):\r\n    # Read-only fields become non-editable in grid\r\n    total_sales = serializers.ReadOnlyField()\r\n    \r\n    # Custom labels are used in grid headers\r\n    name = serializers.CharField(label=\"Product Name\")\r\n    \r\n    # Field types determine grid column types\r\n    price = serializers.DecimalField(max_digits=10, decimal_places=2)\r\n    in_stock = serializers.BooleanField()\r\n    created_at = serializers.DateTimeField(read_only=True)\r\n    \r\n    class Meta:\r\n        model = Product\r\n        fields = ['id', 'name', 'price', 'in_stock', 'total_sales', 'created_at']\r\n```\r\n\r\n### Field Type Mappings\r\n\r\nThe package automatically maps Django field types to jqGrid column configurations:\r\n\r\n| Django Field Type | jqGrid Configuration |\r\n|------------------|---------------------|\r\n| CharField | `stype: 'text'`, search operators: eq, ne, cn, nc, bw, bn, ew, en |\r\n| IntegerField | `stype: 'integer'`, `align: 'right'`, search operators: eq, ne, lt, le, gt, ge |\r\n| DecimalField | `stype: 'number'`, `align: 'right'`, with decimal places |\r\n| BooleanField | `stype: 'checkbox'`, `align: 'center'` |\r\n| DateField | `stype: 'date'`, with datepicker |\r\n| DateTimeField | `stype: 'datetime-local'`, with datetimepicker |\r\n| ForeignKey | `stype: 'select'`, with dropdown data URL |\r\n| EmailField | `stype: 'email'`, `formatter: 'email'` |\r\n| URLField | `stype: 'text'`, `formatter: 'link'` |\r\n\r\n### ViewSet Configuration Options\r\n\r\n```python\r\nclass ProductViewSet(JqGridConfigMixin, JqGridBulkActionMixin, viewsets.ModelViewSet):\r\n    queryset = Product.objects.all()\r\n    serializer_class = ProductSerializer\r\n    \r\n    # Column visibility\r\n    visible_columns = ['id', 'name', 'price', 'in_stock', 'created_at']\r\n    \r\n    # Search configuration\r\n    search_fields = ['name', 'description', 'sku']\r\n    \r\n    # Sorting configuration\r\n    ordering_fields = ['name', 'price', 'created_at']\r\n    ordering = ['-created_at', 'name']  # Default sort\r\n    \r\n    # Grouping configuration\r\n    groupable_fields = ['category', 'brand']\r\n    \r\n    # Frozen columns (stay visible when scrolling)\r\n    frozen_columns = ['id', 'name']\r\n    \r\n    # Bulk operations\r\n    bulk_updateable_fields = ['price', 'in_stock', 'category']\r\n    bulk_actions = [\r\n        {\r\n            'id': 'bulk-update-price',\r\n            'label': 'Update Price',\r\n            'icon': 'fa-dollar',\r\n            'class': 'btn-warning'\r\n        },\r\n        {\r\n            'id': 'bulk-delete',\r\n            'label': 'Delete Selected',\r\n            'icon': 'fa-trash',\r\n            'class': 'btn-danger'\r\n        }\r\n    ]\r\n    \r\n    # Field overrides\r\n    jqgrid_field_overrides = {\r\n        'price': {\r\n            'formatter': 'currency',\r\n            'formatoptions': {'prefix': '$', 'decimalPlaces': 2}\r\n        }\r\n    }\r\n    \r\n    # Grid options override\r\n    jqgrid_options_override = {\r\n        'rowNum': 50,\r\n        'height': 600,\r\n        'caption': 'Product Inventory'\r\n    }\r\n    \r\n    # Conditional formatting\r\n    conditional_formatting = {\r\n        'in_stock': {\r\n            'false': {'color': 'red', 'background': '#ffeeee'},\r\n            'true': {'color': 'green', 'background': '#eeffee'}\r\n        },\r\n        'price': {\r\n            'condition': 'value > 1000',\r\n            'style': {'fontWeight': 'bold', 'color': 'blue'}\r\n        }\r\n    }\r\n```\r\n\r\n## Advanced Features\r\n\r\n### 1. Bulk Operations\r\n\r\nThe `JqGridBulkActionMixin` provides bulk update and delete functionality:\r\n\r\n```javascript\r\n// Bulk update example\r\n$.ajax({\r\n    url: '/api/products/bulk_action/',\r\n    method: 'POST',\r\n    data: JSON.stringify({\r\n        ids: [1, 2, 3],\r\n        action: {\r\n            price: 29.99,\r\n            in_stock: true\r\n        }\r\n    }),\r\n    contentType: 'application/json'\r\n});\r\n\r\n// Bulk delete example\r\n$.ajax({\r\n    url: '/api/products/bulk_action/',\r\n    method: 'POST',\r\n    data: JSON.stringify({\r\n        ids: [1, 2, 3],\r\n        action: {\r\n            _delete: true\r\n        }\r\n    }),\r\n    contentType: 'application/json'\r\n});\r\n```\r\n\r\n### 2. Custom Grid Filters\r\n\r\nUsers can save and manage custom grid filters:\r\n\r\n```python\r\n# The package includes GridFilter model for storing user filters\r\nfrom django_jqgrid.models import GridFilter\r\n\r\n# Filters are automatically available in the grid search dialog\r\n# Users can save search criteria as named filters\r\n```\r\n\r\n### 3. Import/Export Configuration\r\n\r\n```python\r\nclass ProductViewSet(JqGridConfigMixin, viewsets.ModelViewSet):\r\n    # ... other configuration ...\r\n    \r\n    import_config = {\r\n        'supported_formats': ['csv', 'xlsx', 'json'],\r\n        'field_mapping': {\r\n            'Product Name': 'name',\r\n            'Price': 'price',\r\n            'Stock': 'in_stock'\r\n        }\r\n    }\r\n    \r\n    export_config = {\r\n        'formats': ['csv', 'xlsx', 'pdf'],\r\n        'include_headers': True,\r\n        'max_rows': 10000\r\n    }\r\n```\r\n\r\n### 4. Row Grouping\r\n\r\n```python\r\nclass OrderViewSet(JqGridConfigMixin, viewsets.ModelViewSet):\r\n    # ... other configuration ...\r\n    \r\n    groupable_fields = ['status', 'customer', 'date']\r\n    aggregation_fields = {\r\n        'total': 'sum',\r\n        'items_count': 'count'\r\n    }\r\n```\r\n\r\n## API Endpoints\r\n\r\nThe package automatically creates these endpoints for each model:\r\n\r\n- `GET /api/<app>/<model>/` - List/search records with jqGrid parameters\r\n- `GET /api/<app>/<model>/jqgrid_config/` - Get grid configuration\r\n- `POST /api/<app>/<model>/crud/` - Handle jqGrid CRUD operations\r\n- `POST /api/<app>/<model>/bulk_action/` - Bulk update/delete\r\n- `GET /api/<app>/<model>/dropdown/` - Get dropdown data for foreign keys\r\n\r\n## Settings\r\n\r\n```python\r\n# settings.py\r\n\r\n# Default grid options (optional)\r\nJQGRID_DEFAULT_GRID_OPTIONS = {\r\n    'rowNum': 25,\r\n    'rowList': [25, 50, 100, 500, 1000],\r\n    'height': 400,\r\n    'styleUI': 'Bootstrap4',\r\n    'iconSet': 'fontAwesome'\r\n}\r\n\r\n# Default field type configurations (optional)\r\nJQGRID_DEFAULT_FIELD_CONFIG = {\r\n    'DateField': {\r\n        'formatoptions': {\"srcformat\": \"ISO8601Short\", \"newformat\": \"d/m/Y\"}\r\n    }\r\n}\r\n```\r\n\r\n## JavaScript Integration\r\n\r\nThe package includes JavaScript utilities for enhanced functionality:\r\n\r\n```javascript\r\n// jqgrid-integration.js provides helper functions\r\n\r\n// Handle form responses\r\nwindow.handleFormResponse = function(response, postdata) {\r\n    // Custom response handling\r\n};\r\n\r\n// Handle export\r\nwindow.handleExport = function() {\r\n    // Export grid data\r\n};\r\n\r\n// Handle import\r\nwindow.handleImport = function() {\r\n    // Import data dialog\r\n};\r\n```\r\n\r\n## Theme Configuration\r\n\r\nDjango jqGrid supports multiple themes and can be easily customized to match your application's design.\r\n\r\n### Using the Theme Template Tag\r\n\r\n```django\r\n{% load jqgrid_tags %}\r\n\r\n<!-- Use default theme (Bootstrap 4) -->\r\n{% jqgrid_theme %}\r\n\r\n<!-- Specify theme and icon set -->\r\n{% jqgrid_theme 'bootstrap5' 'fontAwesome' %}\r\n\r\n<!-- Use custom CSS -->\r\n{% jqgrid_theme theme='bootstrap4' custom_css='/static/css/my-grid-theme.css' %}\r\n```\r\n\r\n### Available Themes\r\n\r\n- **bootstrap** - Bootstrap 3 theme\r\n- **bootstrap4** - Bootstrap 4 theme (default)\r\n- **bootstrap5** - Bootstrap 5 theme\r\n- **jqueryui** - jQuery UI theme\r\n\r\n### Available Icon Sets\r\n\r\n- **fontAwesome** - Font Awesome icons (default)\r\n- **bootstrap** - Bootstrap Icons\r\n- **jQueryUI** - jQuery UI icons\r\n- **glyph** - Glyphicons (Bootstrap 3)\r\n\r\n### Settings-Based Configuration\r\n\r\nConfigure theme globally in your Django settings:\r\n\r\n```python\r\n# settings.py\r\nJQGRID_THEME = 'bootstrap5'\r\nJQGRID_ICON_SET = 'fontAwesome'\r\nJQGRID_CUSTOM_CSS = '/static/css/custom-grid.css'\r\n```\r\n\r\n### Dynamic Theme Switching\r\n\r\nInclude the theme switcher component:\r\n\r\n```html\r\n<!-- Theme switcher container -->\r\n<div id=\"theme-switcher\"></div>\r\n\r\n<!-- Include theme switcher JS -->\r\n<script src=\"{% static 'django_jqgrid/js/jqgrid-theme-switcher.js' %}\"></script>\r\n\r\n<script>\r\n// Initialize theme switcher\r\njqGridThemeSwitcher.init({\r\n    container: '#theme-switcher',\r\n    showPreview: true,\r\n    onChange: function(theme, iconSet) {\r\n        console.log('Theme changed to:', theme, iconSet);\r\n    }\r\n});\r\n</script>\r\n```\r\n\r\n### Custom Theme CSS\r\n\r\nCreate your own theme by overriding CSS variables:\r\n\r\n```css\r\n/* custom-grid-theme.css */\r\n:root {\r\n    /* Grid colors */\r\n    --jqgrid-header-bg: #2c3e50;\r\n    --jqgrid-header-text: #ffffff;\r\n    --jqgrid-row-hover: #ecf0f1;\r\n    --jqgrid-row-selected: #3498db;\r\n    \r\n    /* Borders */\r\n    --jqgrid-border-color: #bdc3c7;\r\n    \r\n    /* Fonts */\r\n    --jqgrid-font-size: 14px;\r\n    --jqgrid-header-font-weight: 600;\r\n}\r\n\r\n/* Dark mode support */\r\n@media (prefers-color-scheme: dark) {\r\n    :root {\r\n        --jqgrid-header-bg: #1a1a1a;\r\n        --jqgrid-row-bg: #2a2a2a;\r\n        --jqgrid-row-alt-bg: #333333;\r\n    }\r\n}\r\n```\r\n\r\n## Customization and Extension\r\n\r\nDjango jqGrid is designed to be highly customizable. Here are some common customization examples:\r\n\r\n### Quick Customization Examples\r\n\r\n#### 1. Custom Formatters\r\n```javascript\r\n// Register a custom status badge formatter\r\nwindow.jqGridConfig.formatters.statusBadge = function(cellval, opts) {\r\n    const statusClasses = {\r\n        'active': 'badge-success',\r\n        'pending': 'badge-warning',\r\n        'inactive': 'badge-danger'\r\n    };\r\n    const badgeClass = statusClasses[cellval] || 'badge-info';\r\n    return `<span class=\"badge ${badgeClass}\">${cellval}</span>`;\r\n};\r\n\r\n// Use in ViewSet\r\njqgrid_field_overrides = {\r\n    'status': {\r\n        'formatter': 'statusBadge',\r\n        'align': 'center'\r\n    }\r\n}\r\n```\r\n\r\n#### 2. Custom Bulk Actions\r\n```python\r\nclass ProductViewSet(JqGridConfigMixin, JqGridBulkActionMixin, viewsets.ModelViewSet):\r\n    # Define custom bulk actions\r\n    bulk_actions = [\r\n        {\r\n            'id': 'apply-discount',\r\n            'label': 'Apply Discount',\r\n            'icon': 'fa-percent',\r\n            'class': 'btn-warning'\r\n        }\r\n    ]\r\n    \r\n    @action(methods=['post'], detail=False)\r\n    def bulk_action(self, request):\r\n        action_id = request.data.get('action_id')\r\n        if action_id == 'apply-discount':\r\n            # Custom logic here\r\n            return Response({'status': 'success'})\r\n        return super().bulk_action(request)\r\n```\r\n\r\n#### 3. JavaScript Hooks\r\n```javascript\r\n// Customize grid behavior using hooks\r\nwindow.jqGridConfig.hooks.beforeInitGrid = function(tableInstance) {\r\n    // Add custom configuration before grid initializes\r\n    tableInstance.options.customData = { department: 'sales' };\r\n};\r\n\r\nwindow.jqGridConfig.hooks.afterSubmitBulkUpdate = function(tableInstance, ids, action, scope, response) {\r\n    // Custom notification after bulk update\r\n    showCustomNotification('Updated ' + ids.length + ' records');\r\n};\r\n```\r\n\r\n#### 4. Dynamic Column Configuration\r\n```python\r\nclass UserAwareProductViewSet(JqGridConfigMixin, viewsets.ModelViewSet):\r\n    def get_visible_columns(self):\r\n        \"\"\"Show different columns based on user permissions\"\"\"\r\n        base_columns = ['id', 'name', 'price']\r\n        \r\n        if self.request.user.has_perm('products.view_cost'):\r\n            base_columns.extend(['cost', 'profit_margin'])\r\n        \r\n        if self.request.user.is_staff:\r\n            base_columns.extend(['supplier', 'internal_notes'])\r\n        \r\n        return base_columns\r\n    \r\n    def get_jqgrid_config(self, request):\r\n        self.visible_columns = self.get_visible_columns()\r\n        return super().get_jqgrid_config(request)\r\n```\r\n\r\n#### 5. Custom Toolbar Buttons\r\n```javascript\r\n// Add custom buttons to specific tables\r\nwindow.jqGridConfig.customButtons.product = [\r\n    {\r\n        id: 'import-csv',\r\n        label: 'Import CSV',\r\n        icon: 'fa-file-csv',\r\n        class: 'btn-success',\r\n        action: function(tableInstance) {\r\n            showImportModal(tableInstance);\r\n        }\r\n    }\r\n];\r\n```\r\n\r\n### Complete Customization Guide\r\n\r\nFor comprehensive customization examples including:\r\n- Advanced ViewSet customization\r\n- Custom field types\r\n- Theme customization\r\n- Real-time updates\r\n- Performance optimization\r\n- Complex real-world examples\r\n\r\nSee the [**Customization Guide**](CUSTOMIZATION_GUIDE.md).\r\n\r\n## Example Project\r\n\r\nThe package includes a complete example project demonstrating all features:\r\n\r\n### Running the Example Project\r\n\r\n```bash\r\n# Navigate to example project\r\ncd example_project\r\n\r\n# Install dependencies\r\npip install -r requirements.txt\r\n\r\n# Setup the project\r\npython setup_example.py\r\n\r\n# Run the server\r\npython manage.py runserver\r\n```\r\n\r\nVisit: `http://localhost:8000/`\r\n\r\n## Security\r\n\r\n- All operations respect Django's permission system\r\n- CSRF protection for all POST requests\r\n- User-specific filters are isolated\r\n- Bulk operations validate field permissions\r\n\r\n## Browser Support\r\n\r\n- Chrome (latest)\r\n- Firefox (latest)\r\n- Safari (latest)\r\n- Edge (latest)\r\n- Mobile browsers (responsive mode)\r\n\r\n## Troubleshooting\r\n\r\n### Common Issues\r\n\r\n#### 1. \"jqgrid_tags is not a registered tag library\"\r\n**Solution:**\r\n- Ensure `django_jqgrid` is in your `INSTALLED_APPS`\r\n- Restart the Django development server\r\n- If developing locally, install the package in editable mode: `pip install -e .`\r\n\r\n#### 2. Grid not loading data\r\n**Solution:**\r\n- Check browser console for JavaScript errors\r\n- Verify the API endpoint is accessible\r\n- Ensure DRF permissions allow access\r\n- Check that the ViewSet URL pattern is correct\r\n\r\n#### 3. Bulk operations not working\r\n**Solution:**\r\n- Verify `JqGridBulkActionMixin` is included in your ViewSet\r\n- Check CSRF token is being sent with requests\r\n- Ensure user has appropriate permissions\r\n\r\n#### 4. Custom formatters not displaying\r\n**Solution:**\r\n- Register formatters before grid initialization\r\n- Check formatter function name matches configuration\r\n- Verify no JavaScript errors in formatter function\r\n\r\n#### 5. Performance issues with large datasets\r\n**Solution:**\r\n- Use server-side pagination (enabled by default)\r\n- Add database indexes on frequently sorted/filtered columns\r\n- Use `select_related()` and `prefetch_related()` in querysets\r\n- Consider implementing caching for frequently accessed data\r\n\r\nFor more detailed troubleshooting, see the [Customization Guide](CUSTOMIZATION_GUIDE.md#troubleshooting).\r\n\r\n## Requirements\r\n\r\n- Python 3.8+\r\n- Django 3.2+\r\n- Django REST Framework 3.12+\r\n\r\n## License\r\n\r\nThis project is licensed under the MIT License - see the LICENSE file for details.\r\n\r\n## Contributing\r\n\r\nContributions are welcome! Please feel free to submit a Pull Request.\r\n\r\n## Support\r\n\r\nFor issues and feature requests, please use the [GitHub issue tracker](https://github.com/coder-aniket/django-jqgrid/issues).\r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A Django app for integrating jqGrid with Django REST Framework",
    "version": "1.2.7",
    "project_urls": {
        "Bug Reports": "https://github.com/coder-aniket/django-jqgrid/issues",
        "Documentation": "https://django-jqgrid.readthedocs.io",
        "Homepage": "https://github.com/coder-aniket/django-jqgrid",
        "Source": "https://github.com/coder-aniket/django-jqgrid"
    },
    "split_keywords": [
        "django",
        " jqgrid",
        " rest",
        " framework",
        " grid",
        " datatable"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "53de5d24d00c7acd0b975241d592b22aa4e2abbff0c01e174ceae0b5a38caf23",
                "md5": "234d5a6bd4df5cceadff789a2f387b9b",
                "sha256": "08a805afe4ff78134346b80232c49a06b7144f344b29b93f8ca054fa6d5cba33"
            },
            "downloads": -1,
            "filename": "django_jqgrid-1.2.7-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "234d5a6bd4df5cceadff789a2f387b9b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 1214284,
            "upload_time": "2025-07-22T18:39:34",
            "upload_time_iso_8601": "2025-07-22T18:39:34.768036Z",
            "url": "https://files.pythonhosted.org/packages/53/de/5d24d00c7acd0b975241d592b22aa4e2abbff0c01e174ceae0b5a38caf23/django_jqgrid-1.2.7-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "c462c5d408e16d4d70e92795c08f8196bbf891b520bc7aeef1d8b58a3ac5ee8d",
                "md5": "0ba6438aa0fc815644b6e814108fe57e",
                "sha256": "d5a3a5a756c8c908ff1a6c731ee872df5985b9bd1754a0cebb66cc0dbbc5400a"
            },
            "downloads": -1,
            "filename": "django_jqgrid-1.2.7.tar.gz",
            "has_sig": false,
            "md5_digest": "0ba6438aa0fc815644b6e814108fe57e",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 1113510,
            "upload_time": "2025-07-22T18:39:38",
            "upload_time_iso_8601": "2025-07-22T18:39:38.292251Z",
            "url": "https://files.pythonhosted.org/packages/c4/62/c5d408e16d4d70e92795c08f8196bbf891b520bc7aeef1d8b58a3ac5ee8d/django_jqgrid-1.2.7.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-22 18:39:38",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "coder-aniket",
    "github_project": "django-jqgrid",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "Django",
            "specs": [
                [
                    ">=",
                    "3.2"
                ],
                [
                    "<",
                    "5.0"
                ]
            ]
        },
        {
            "name": "djangorestframework",
            "specs": [
                [
                    ">=",
                    "3.12.0"
                ]
            ]
        },
        {
            "name": "django-filter",
            "specs": [
                [
                    ">=",
                    "21.1"
                ]
            ]
        }
    ],
    "lcname": "django-jqgrid"
}
        
Elapsed time: 1.13970s