Skip to content

Commit

Permalink
V2: Deprecate lazy add optional (#59)
Browse files Browse the repository at this point in the history
* have actions run on PRs

* deprecate lazy and add optional
  • Loading branch information
BrandonShar authored Jan 4, 2025
1 parent 385b700 commit 36e2974
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 14 deletions.
10 changes: 9 additions & 1 deletion .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
name: Unit tests

on: [push]
on:
push:
branches:
- main
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'

jobs:
unit-test:
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,7 @@ cython_debug/
#.idea/

# because this is a package, we don't want to commit the lock file
poetry.lock
poetry.lock

.DS_Store
.tool-versions
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,25 +131,25 @@ def external():
It will generate a `409 Conflict` response and include the destination URL in the `X-Inertia-Location` header.
When this response is received client-side, Inertia will automatically perform a `window.location = url` visit.

### Lazy Props
### Optional Props

On the front end, Inertia supports the concept of "partial reloads" where only the props requested
are returned by the server. Sometimes, you may want to use this flow to avoid processing a particularly slow prop on the intial load. In this case, you can use `Lazy props`. Lazy props aren't evaluated unless they're specifically requested by name in a partial reload.
are returned by the server. Sometimes, you may want to use this flow to avoid processing a particularly slow prop on the intial load. In this case, you can use `Optional props`. Optional props aren't evaluated unless they're specifically requested by name in a partial reload.

```python
from inertia import lazy, inertia
from inertia import optional, inertia

@inertia('ExampleComponent')
def example(request):
return {
'name': lambda: 'Brandon', # this will be rendered on the first load as usual
'data': lazy(lambda: some_long_calculation()), # this will only be run when specifically requested by partial props and WILL NOT be included on the initial load
'data': optional(lambda: some_long_calculation()), # this will only be run when specifically requested by partial props and WILL NOT be included on the initial load
}
```

### Deferred Props

As of version 2.0, Inertia supports the ability to defer the fetching of props until after the page has been initially rendered. Essentially this is similar to the concept of `Lazy props` however Inertia provides convenient frontend components to automatically fetch the deferred props after the page has initially loaded, instead of requiring the user to initiate a reload. For more info, see [Deferred props](https://inertiajs.com/deferred-props) in the Inertia documentation.
As of version 2.0, Inertia supports the ability to defer the fetching of props until after the page has been initially rendered. Essentially this is similar to the concept of `Optional props` however Inertia provides convenient frontend components to automatically fetch the deferred props after the page has initially loaded, instead of requiring the user to initiate a reload. For more info, see [Deferred props](https://inertiajs.com/deferred-props) in the Inertia documentation.

To mark props as deferred on the server side use the `defer` function.

Expand Down
2 changes: 1 addition & 1 deletion inertia/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from .http import inertia, render, location
from .utils import lazy, defer
from .utils import lazy, optional, defer
from .share import share
26 changes: 21 additions & 5 deletions inertia/tests/test_rendering.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from inertia.test import InertiaTestCase, inertia_div, inertia_page
from pytest import warns

class FirstLoadTestCase(InertiaTestCase):
def test_with_props(self):
Expand Down Expand Up @@ -74,15 +75,30 @@ def test_redirects_from_inertia_views(self):

class LazyPropsTestCase(InertiaTestCase):
def test_lazy_props_are_not_included(self):
with warns(DeprecationWarning):
self.assertJSONResponse(
self.inertia.get('/lazy/'),
inertia_page('lazy', props={'name': 'Brian'})
)

def test_lazy_props_are_included_when_requested(self):
with warns(DeprecationWarning):
self.assertJSONResponse(
self.inertia.get('/lazy/', HTTP_X_INERTIA_PARTIAL_DATA='sport,grit', HTTP_X_INERTIA_PARTIAL_COMPONENT='TestComponent'),
inertia_page('lazy', props={'sport': 'Basketball', 'grit': 'intense'})
)

class OptionalPropsTestCase(InertiaTestCase):
def test_optional_props_are_not_included(self):
self.assertJSONResponse(
self.inertia.get('/lazy/'),
inertia_page('lazy', props={'name': 'Brian'})
self.inertia.get('/optional/'),
inertia_page('optional', props={'name': 'Brian'})
)

def test_lazy_props_are_included_when_requested(self):
def test_optional_props_are_included_when_requested(self):
self.assertJSONResponse(
self.inertia.get('/lazy/', HTTP_X_INERTIA_PARTIAL_DATA='sport,grit', HTTP_X_INERTIA_PARTIAL_COMPONENT='TestComponent'),
inertia_page('lazy', props={'sport': 'Basketball', 'grit': 'intense'})
self.inertia.get('/optional/', HTTP_X_INERTIA_PARTIAL_DATA='sport,grit', HTTP_X_INERTIA_PARTIAL_COMPONENT='TestComponent'),
inertia_page('optional', props={'sport': 'Basketball', 'grit': 'intense'})
)

class ComplexPropsTestCase(InertiaTestCase):
Expand Down
1 change: 1 addition & 0 deletions inertia/tests/testapp/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
path('props/', views.props_test),
path('template_data/', views.template_data_test),
path('lazy/', views.lazy_test),
path('optional/', views.optional_test),
path('defer/', views.defer_test),
path('defer-group/', views.defer_group_test),
path('complex-props/', views.complex_props_test),
Expand Down
10 changes: 9 additions & 1 deletion inertia/tests/testapp/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.http.response import HttpResponse
from django.shortcuts import redirect
from django.utils.decorators import decorator_from_middleware
from inertia import inertia, render, lazy, defer, share, location
from inertia import inertia, render, lazy, optional, defer, share, location
from inertia.http import INERTIA_SESSION_CLEAR_HISTORY, clear_history, encrypt_history

class ShareMiddleware:
Expand Down Expand Up @@ -52,6 +52,14 @@ def lazy_test(request):
'grit': lazy(lambda: 'intense'),
}

@inertia('TestComponent')
def optional_test(request):
return {
'name': 'Brian',
'sport': optional(lambda: 'Basketball'),
'grit': optional(lambda: 'intense'),
}

@inertia('TestComponent')
def defer_test(request):
return {
Expand Down
13 changes: 13 additions & 0 deletions inertia/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from django.db import models
from django.db.models.query import QuerySet
from django.forms.models import model_to_dict as base_model_to_dict
import warnings

def model_to_dict(model):
return base_model_to_dict(model, exclude=('password',))
Expand All @@ -18,10 +19,19 @@ def default(self, value):

class LazyProp:
def __init__(self, prop):
warnings.warn(
"lazy and LazyProp are deprecated and will be removed in a future version. Please use optional instead.",
DeprecationWarning,
stacklevel=2
)
self.prop = prop

def __call__(self):
return self.prop() if callable(self.prop) else self.prop

class OptionalProp(LazyProp):
def __init__(self, prop):
self.prop = prop

class DeferredProp:
def __init__(self, prop, group):
Expand All @@ -34,5 +44,8 @@ def __call__(self):
def lazy(prop):
return LazyProp(prop)

def optional(prop):
return OptionalProp(prop)

def defer(prop, group="default"):
return DeferredProp(prop, group)

0 comments on commit 36e2974

Please sign in to comment.