Comments (4)
commented by @jansule on issue
Do I understand correctly that you want to use AsyncUpdateView
on any arbitrary model? And by coupling the async_task to the model, you are able to reuse this view more easily, as the async task might differ or might not be used at all between different models?
If so, then following comes to my mind:
- Do we have a model, where we ALWAYS want to call an async_task on certain save-conditions?
If yes, then I would say that this concept should work fine.
If not, I would think about another way of coupling the task with the view. As far as I understand, we have to inherit from the AsyncUpdateView
for each model anyways, in order to pass the respective model to the view.
We could then use method decorators to add the async_task where needed, like so (simplified example):
class AsyncUpdateView(UpdateView):
# ...
def form_valid(self, form, task=None):
self.object.save()
content = {
"task": {
"alert": Alert(msg=self.alert_msg, alert_type=AlertEnum.SUCCESS).render()
},
}
if (task is not None):
content["task"]["id"]: task.task_id
# cause this is a async task which can take longer we response with 'accept' status
return JsonResponse(status=202, data=content)
@method_decorator(async_task_func, 'form_valid')
class ServiceForm(AsyncUpdateView):
model = Service
# we do not have to overwrite from_valid() here
Using method_decorators on the views would have the benefit of having a softer coupling between model and async_task.
Please note that the two concepts can be used at the same time, depending on the answer for above mentioned question.
side note
I'm not too familiar on what's happening in the async_task of your example. But shouldn't the isActive
property be set to true
AFTER the async_task is finished?
from mrmap.
Do I understand correctly that you want to use AsyncUpdateView on any arbitrary model?
Yes
And by coupling the async_task to the model, you are able to reuse this view more easily, as the async task might differ or might not be used at all between different models?
Yes that's why i think we could use django signals here. Then it is a normal UpdateView which changes the is_active
attribute of the Metadata model in this case.
Do we have a model, where we ALWAYS want to call an async_task on certain save-conditions?
No - we don't need to call an async_task always. So for that we could implement a custom django signal. Example:
class Metadata:
__original_is_active = None
def __init__(self, *args, **kwargs):
super(Metadata, self).__init__(*args, **kwargs)
self.__original_is_active = self.is_active
...
@receiver(post_save, sender=Metadata)
def is_active_changed(sender, instance, created, raw, using, update_fields, **kwargs):
if 'is_active' in update_fields and instance.is_active != instance.__original_is_active:
tasks.async_activate_deactivate_service(instance.id)
As far as I understand, we have to inherit from the AsyncUpdateView for each model anyways, in order to pass the respective model to the view.
IF the example above works, the AsyncUpdateView
could be refactored to not call any tasks. I would like to only update the model with is_active
field.
We could then use method decorators to add the async_task where needed, like so (simplified example):
Good solution as well to make it more generic
I’m not too familiar on what’s happening in the async_task of your example. But shouldn’t the isActive property be set to true AFTER the async_task is finished?
I think after refactoring with signals we should first save the new is_active
value. And the activation task should get the new value from model.
Current implementation: The task get the instance of the model by id from the db if the celery schedule the task. After that all sub elements of the current instance will be traversed to change the is_active
attribute to the new value.
from mrmap.
commented by @jansule :
I like your idea.
Currently, I see two different cases:
- ALWAYS trigger a task when a certain value changes -> hard coupling via django signals on the model
- SOMETIMES trigger a task when a certain value changes -> soft coupling via method decorators
This is something we will have to consider for each case. For your example, case 1 seems to be the better approach.
But there might be cases, where a value will be changed at different locations in the code, but a method should not always be triggered.
Let's say we have a value that can be changed by a user in the frontend, but will also be changed in some processing in the backend. We only want to call a method, if the value was directly set by the user.
So as long as we know for a certain case if we want a hard or a soft coupling, we can go with the appropriate pattern.
In any way, we do not have to implement the async task within the AsyncUpdateView
, which sounds like a benefit to me.
So +1 on that
from mrmap.
I found a nice article with explanations where signals should be live: https://simpleisbetterthancomplex.com/tutorial/2016/07/28/how-to-create-django-signals.html
from mrmap.
Related Issues (20)
- Map Context Editor: ZoomToExtent context menu
- WMS Security Proxy Settings
- Security Proxy: AllowedWebMapServiceOperation CheckContraints
- Security Proxy: WMS proxy secured layer behaviour
- WMS Security Proxy Settings: Skeleton
- WMS Security Proxy Settings
- WMS Security Proxy Settings: Layer Tree
- WMS Security Proxy Settings: Rule List
- WMS Security Proxy Settings: Rule Settings Basics
- WMS Security Proxy Settings: Rule Settings Groups
- WMS Security Proxy Settings: Rule Settings operations
- WMS Security Proxy Settings: Rule Settings spatial constraints (WKT)
- WMS Security Proxy Settings: Rule Settings spatial constraints (interactive)
- WMS Security Proxy Settings: Display WMS security information
- MapContextForm/WmsSecuritySettings: Move right drawer to bottom HOT 1
- Frontend: Enable i18n HOT 1
- Frontend: Use useOperationMethod/JsonApiUtils instead of JsonApiRepo classes HOT 1
- MapContextForm: Reimplement based on react-geo LayerTree
- OpenAPI mismatched with JSON:API HOT 1
- migrate from django-mptt to django-treebeard
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mrmap.