@@ -222,6 +222,20 @@ Method ``per_save_model`` is called before saving object to database. Body is em
222222
223223Method ``post_save_model `` is called after saving object to database. Body is empty by default.
224224
225+ **Example: Additional Processing After Save **
226+
227+ Perform additional processing after an object is successfully saved::
228+
229+ class CustomerCore(DjangoUiRestCore):
230+ model = Customer
231+
232+ def post_save_model(self, request, obj, form, change):
233+ super().post_save_model(request, obj, form, change)
234+
235+ # Trigger communication for newly registered customers
236+ if not change: # Only for new customers
237+ trigger_customer_registered_communication(obj)
238+
225239.. method :: DjangoCore.save_model(request, obj, form, change)
226240
227241You can rewrite this method if you want to change way how is object saved to database. Default body is::
@@ -273,6 +287,26 @@ improve a speed of your application use this function to create preloading of re
273287
274288Use this method if you want to change ``list_actions `` dynamically.
275289
290+ **Example: Dynamic Actions Based on State **
291+
292+ Add actions that depend on object state::
293+
294+ class ArticleCore(DjangoUiRestCore):
295+ model = Article
296+
297+ def get_list_actions(self, request, obj):
298+ actions = super().get_list_actions(request, obj)
299+
300+ # Add publish action only for draft articles
301+ if obj.status == 'draft':
302+ actions.append({
303+ 'url': self.get_rest_url('publish', pk=obj.pk),
304+ 'verbose_name': _('Publish'),
305+ 'action': 'publish',
306+ })
307+
308+ return actions
309+
276310
277311.. method :: DjangoCore.get_default_action(request, obj)
278312
@@ -297,6 +331,21 @@ Every UI core has one place inside menu that addresses one of UI views of a core
297331Option `show_in_menu ` is set to ``True `` by default. If you want to remove core view from menu set this option to
298332``False ``.
299333
334+ **Example Usage **
335+
336+ Hide utility cores from the main navigation::
337+
338+ class CustomerImportCore(DjangoUiRestCore):
339+ """Internal core for CSV import - not shown in menu"""
340+ model = Customer
341+ show_in_menu = False # Hidden from navigation
342+ menu_url_name = None # No menu link
343+
344+ class CustomerAuditLogCore(DjangoRestCore):
345+ """API-only core for audit logs"""
346+ model = CustomerAuditLog
347+ show_in_menu = False # REST-only, no UI
348+
300349.. attribute :: UiCore.view_classes
301350
302351Option contains view classes that are automatically added to Django urls. Use this option to add new views. Example
@@ -317,6 +366,37 @@ you can see in section generic views (this is a declarative way if you want to r
317366 ('reports', r'^/reports/$', MonthReportView),
318367 )
319368
369+ **Complex Example **
370+
371+ Register multiple custom views with specific permissions::
372+
373+ class CustomerCore(DjangoUiRestCore):
374+ model = Customer
375+
376+ view_classes = (
377+ # Custom detail view with tabs
378+ ('change', r'^/(?P<pk>[^/]+)/$', CustomerDetailView, False, False),
379+
380+ # Related object management
381+ ('add-address', r'^/(?P<customer_pk>[^/]+)/address/add/$', AddressAddView, False, True),
382+ ('edit-address', r'^/(?P<customer_pk>[^/]+)/address/(?P<pk>[^/]+)/$', AddressDetailView, False, False),
383+
384+ # Custom actions with parent scoping
385+ ('activate', r'^/(?P<pk>[^/]+)/activate/$', CustomerActivateView, False, False),
386+ ('deactivate', r'^/(?P<pk>[^/]+)/deactivate/$', CustomerDeactivateView, False, False),
387+
388+ # Bulk operations
389+ ('bulk-export', r'^/bulk-export/$', CustomerBulkExportView, False, False),
390+ )
391+
392+ The tuple format is: ``(url_name_suffix, url_pattern, view_class, can_create, can_delete) ``
393+
394+ - ``url_name_suffix ``: Suffix added to core's base URL name
395+ - ``url_pattern ``: Regular expression for URL matching
396+ - ``view_class ``: The view class to use
397+ - ``can_create ``: Boolean indicating if this view can create objects (default: False)
398+ - ``can_delete ``: Boolean indicating if this view can delete objects (default: False)
399+
320400.. attribute :: UiCore.default_ui_pattern_class
321401
322402Every view must have assigned is-core pattern class. This pattern is not the same patter that is used with **django **
@@ -419,6 +499,52 @@ Use this method if you want to change ``rest_classes`` dynamically.
419499
420500Contains code that generates ``rest_patterns `` from rest classes. Method returns an ordered dict of pattern classes.
421501
502+ **Example: Custom REST Endpoints **
503+
504+ Add custom REST endpoints alongside standard CRUD operations::
505+
506+ from django.conf.urls import patterns, url
507+
508+ class CustomerCore(DjangoUiRestCore):
509+ model = Customer
510+
511+ def get_rest_patterns(self):
512+ # Get default patterns (list, detail, create, update, delete)
513+ rest_patterns = super().get_rest_patterns()
514+
515+ # Add custom action endpoints
516+ rest_patterns.update({
517+ 'activate': (
518+ r'^/(?P<pk>[^/]+)/activate/$',
519+ self.resource_class,
520+ {'allowed_methods': ('post',)}
521+ ),
522+ 'deactivate': (
523+ r'^/(?P<pk>[^/]+)/deactivate/$',
524+ self.resource_class,
525+ {'allowed_methods': ('post',)}
526+ ),
527+ 'bulk-export': (
528+ r'^/bulk-export/$',
529+ self.resource_class,
530+ {'allowed_methods': ('post',)}
531+ ),
532+ 'stats': (
533+ r'^/stats/$',
534+ CustomerStatsResource,
535+ {'allowed_methods': ('get',)}
536+ ),
537+ })
538+
539+ return rest_patterns
540+
541+ This creates additional REST endpoints:
542+
543+ - ``POST /api/customer/{pk}/activate/ `` - Activate customer
544+ - ``POST /api/customer/{pk}/deactivate/ `` - Deactivate customer
545+ - ``POST /api/customer/bulk-export/ `` - Export multiple customers
546+ - ``GET /api/customer/stats/ `` - Get customer statistics
547+
422548HomeUiCore
423549------------
424550
@@ -729,6 +855,61 @@ Use ``rest_extra_fields`` to define extra fields that is not returned by default
729855by a HTTP header ``X-Fields `` or a GET parameter ``_fields ``. More info you can find in **django-piston ** library
730856documentation. This option rewrites settings inside ``RESTMeta `` (you can find more about it at section #TODO add link).
731857
858+ **Example: API-Only Fields **
859+
860+ Expose computed or aggregated data via REST API without including it in default responses.
861+
862+ Define the fields in your Core::
863+
864+ class CustomerCore(DjangoUiRestCore):
865+ model = Customer
866+
867+ # Fields only available when explicitly requested via API
868+ rest_extra_fields = (
869+ 'coin_balance', # Computed field
870+ 'applied_promocodes_id', # Filterable field
871+ )
872+
873+ # Allow filtering by extra fields in REST API
874+ rest_extra_filter_fields = (
875+ 'applied_promocodes_id',
876+ )
877+
878+ Then define the computed fields in your Resource::
879+
880+ from is_core.utils.decorators import short_description
881+ from pyston.utils.decorators import filter_class
882+
883+ class CustomerResource(DjangoCoreResource):
884+ model = Customer
885+
886+ @short_description(_('Coin Balance'))
887+ def coin_balance(self, obj):
888+ return CoinTransaction.objects.compute_balance_for_customer(obj)
889+
890+ # For filterable extra fields, use @filter_class decorator
891+ @filter_class(AppliedPromocodeIDFilter)
892+ @property
893+ def applied_promocodes_id(self):
894+ return None # Return value not used, filter handles the logic
895+
896+ This pattern is useful for:
897+
898+ - **Performance **: Expensive computed fields are only calculated when needed
899+ - **API flexibility **: Frontend can request additional data without changing default payload
900+ - **Separation **: REST-only data doesn't clutter UI field definitions
901+
902+ Usage example::
903+
904+ # Default API call - excludes extra fields
905+ GET /api/customers/?limit=20
906+
907+ # Request with extra fields
908+ GET /api/customers/?_fields=id,name,coin_balance,applied_promocodes_id
909+
910+ # Filter by extra field (requires @filter_class decorator)
911+ GET /api/customers/?applied_promocodes_id__icontains=PROMO123
912+
732913.. attribute :: DjangoRestCore.rest_default_guest_fields
733914
734915``rest_guest_fields `` contains list of fields that can be seen by user that has not permission to see the whole
0 commit comments