Django Tastypie, use other resource in obj_create method - django

I'm playing around with tastypie, and is pretty much a newbie ;)
I have a FieldResource and want to call a EventLogResource every time there is field is created or updated ..
I think I have to use the obj_create method to call to EventLogResource this is my bad attempt..:
class FieldResource(ModelResource):
def obj_create(self, bundle, **kwargs):
bundle = super(FieldResource, self).obj_create(bundle,**kwargs)
# what to do here??
EventLogResource.create_obj(user=bundle.request.user, comment="test").save()
...
Anyone know how to do this the best way?

Why resource? Create and save model.
EventLog(user=bundle.request.user, comment="test").save()

Related

Is it okay to call django functions through an API?

I'm building a project and now I'm new to VueJS I'm currently learning it. and I found that you can make HTTP Requests on APIs using axios. And to make my project easy, Can I call functions on my views.py thru axios?
Like I'm fetching urls in urls.py to execute some functions on my backend.
Is it okay? I mean for security and best practices. etc.
Thanks
Absolutely ok, that's what Django is for:
urls.py:
urlpatterns = [
...
path('my_view_function/', views.my_view_function, name='my_view_function'),
...
]
views.py:
def my_view_function(request):
# unpack data:
my_value = request.GET['my_key']
# some logic:
...
# pack response:
response = json.dumps({
'some_other_key' : 'some_other_value'
})
return HttpResponse(response)
Another option is that you use signals in django, some time ago I used signals that for when a new record is created without a field, it will be completed with the algorithm you want, for example an order and automatically placed a code, you can apply it only by pointing to your models, when you want something more punctual.
#receiver(pre_save, sender=MyModel)
def my_handler(sender, **kwargs):
...
The my_handler function will only be called when an instance of MyModel is saved.
Here I leave the documentation in case you want to review it
https://docs.djangoproject.com/en/3.1/topics/signals/

How to detect all model's insert or update actions on django framework?

i use django cache system. I want to that when anyone update or insert model, django cache clean. I think, if i get this question's answer i can do it :) also i want to advice for fix this problem. Thank you.
My Example signal;
from django.core.cache import cache
#receiver(post_save, sender=ModelName)
def cache_celan(sender, created, instance, **kwargs):
print("anyone created something so i clean cache.")
cache.clear()
This nice way but i can use it for only model. Is possible i use for it all model?
Thank you.
I find this question's answer :)
if you use "None" for sender, signals detect all model.
from django.core.cache import cache
#receiver(post_save, sender=None)
def cache_celan(sender, created, instance, **kwargs):
print("anyone created or updated something so i clean cache.")
cache.clear()

Django rollback transaction after perform_create

I am trying to use transaction.atomic with django without any luck I know I am doing something wrong but I dont know what.
class SnapshotView(BaseViewSet):
serializer_class = SnapshotSerializer
#transaction.atomic
def perform_create(self, serializer):
# this will call serializer.save()
snapshot = snapshot = super().perform_create(serializer)
# this will run some code can raise an exception
SnapshotServices.create_snapshot(snapshot=snapshot,
data=serializer.initial_data)
the first method that creates a new snapshot will pass the second will raise but still I can see my snapshot instance in the db, why is that?
I am in transaction block and something fails, is django not suppose to do a rollback?
the second method will throw a custom exception
I read the doc and it seems that I am doing everything right.
I figure it out.
my problem was that django uses default DB when using in atomic is None. Because I am using different DB, I just added using to my decorator
transaction.atomic(using=MYDB)
and that's fix my problem.

Add extra context variables into django oscar emails

Trying to add extra context variables for all django oscar email templates. The only way I've got it to work is overriding specific views like ProfileUpdateView. This method seems very messy, I'd have to override a lot of files. Is there a better way of doing this?
From checking the source code, the ProfileUpdateView uses Django's Class Based View FormView, which in turn implements the get_context_data method allowing the injection of extra data in the view.
You can simply create a view inehiriting ProfileUpdateView and override the get_context_data:
class MyProfileUpdateView(ProfileUpdateView):
...
def get_context_data(self, **kwargs):
context = super(MyProfileUpdateView, self).get_context_data(**kwargs)
context['somevar'] = SomeQueryMaybe.objects.all()
return context
Ended up making a custom management command to do it manually since the need to change the emails templates would be really rare.

Is there before_filter in django as in rails?

Is there any feature available in django so that we can combine some filtering on all actions in the view of django, like before_filter: is available in rails.
I'm still learning Rails but from what I've observed so far python decorators also seem to be used in Django in a very similar way to the before_filter in Rails.
Here's one example of it's usage in authenticating users: https://docs.djangoproject.com/en/1.2/topics/auth/#the-login-required-decorator
No. before_, around_ and after_ filter concepts aren't present in Django, but it isn't hard to write your own functions to do the same thing. There are also signals and generic views that might accomplish what you're needing to do.
decorators can be used for this. your decorator can be the before_filter or after_filter depending on how whether it calls the decorated function first or last.
here is an example
#question_required
def show(request, question_id):
return HttpResponse(f'you are looking at {question_id}')
Here we have decorated the show function with question_required and want it to act as a before_filter. so we will define the decorator like this:
def question_required(func):
def containing_func(*args, **kwargs):
request = args[0]
question_id = kwargs['question_id']
try:
question = Question.objects.get(pk=question_id)
except Exception as e:
raise e
return func(*args, **kwargs)
return containing_func
As you can see above the decorator is first checking for the question to exist in the db. If it exists it calls the actual show function or it raises an exception.
In this way it acts like a before filter does in rails.