Adding cache.clear() to global save in Django - django

Hopefully somebody knows a simple way to do this.
Is it possible to run the cache.clear() function on every save to any model?
I know Django docs show you how to implement per model, and overhead isn't an issue. I would like to clear the cache each and every time a change is made.

There are a couple of ways you could do this.
Firstly you could create a common abstract base class that inherits from models.Model and overrides save to do the cache clear, then make all your models inherit from that.
Another way might be to use signals - the pre and post save signals have sender as an optional argument, if you don't specify a particular model it will fire for all models.

#Daniel Rosemen. Sorry as I don't have much reputation I couldn't remove my comment.
Thanks for pointing me in the right direction.
It was as simple as:
from django.db.models.signals import post_save
from django.core.cache import cache
#receiver(post_save)
def clear_the_cache(**kwargs):
cache.clear()

Related

Django - How to trigger an action when a specific model is saved?

I have two models. One called MainModel and other called HistoricMainModel. I would like to INSERT automatically a row in the HistoricMainModel every time I data is inserted to MainModel. What is best/correct way of doing this in Django?
Best Regards,
If you already have some custom save().-magic going on I would recommend using a post_save() signal or a pre_save() which ever would work best for you.
in your models.py
#receiver(pre_save, sender=MainModel)
def save_a_historicmodel(sender, **kwargs):
#do your save historicmodel logic here
or
def save_a_historicmodel(sender, instance, created, **kwargs):
print "Post save was triggered! Instance:", instance
signals.post_save.connect(save_a_historicmodel, sender=MainModel)
This works so that every time your MainModel is saved this signal is triggered.
Docs here
Rewrite save method in MainModel model to create and insert the HistoricMainModel object before calling the "real" save method.
You could implement this yourself but the best way would be to use an application that does this - like reversion - a django app that implements model history/roll back automatically.
In addition to whatever you will implement, reversion will provide you with:
Integration with the admin backend.
A API to add meta-data to your versions and to revert back to previous versions of your model.
It is a lot more flexible and is widely used and implemented.

Do I need to override save method to add data to different models from django UserCreationForm

I want to add another field in UserCreationForm to be shown in RegistrationForm , I saw a couple of examples on stackoverflow for that purpose. I mean the examples by defining different RegisterForm inherited from UserCreationForm as explained in this question of stackoverflow:
django-create-custom-usercreationform-basic
But what will I do, if my data belongs to 2 or 3 different models including User model? Will I then override save method or do some other thing? Is there some way to handle it without going to more low level by just handling it in RegistrationForm that will be inherited from UserCreationForm? What is better way?
Okay, like you see in the link, there are many approaches which you can use, no one of them looks such highlevel as you want.
I don't know how familiar you are with Django, but the linked appraoch looks very promising. It's fresh, uses the signals framework (flexible) and is very easy to implement - high level enough for your problem. Look out for UserProfile Examples because they are very similiar to your Problem and more usual.
If you don't want to go the way with signals, the most straight-forward solution would be to override the save method.
So you already had the solutions in mind. Imho I can't figure out a better or more high level solution.

Use custom Comment app and the default Comment from Django

I have a custom comment app but also want to use the original Comment app, without the added fields of my custom app. Is there a way to do this?
Thanks!
Sure, but if you named your custom app "comments" as well, you'll have to be extra careful to keep things straight. It would probably be best to import Django's comment system like so:
from django.contrib import comments as django_comments
You can then access the comment model like:
django_comments.Comment
Which will signal where it's actually coming from at a glance.

How to override models defined in installed apps in Django?

Is it possible to redefine a model used in an INSTALLED_APP without modifying the app in question? For example, django-basic-blog has a Post model which I would like to add a field to. I could edit django-basic-blog directly but for code portability I'd like to build on top of it. I don't want to subclass as I want to preserve all existing references to the Post model. Thanks in advance!
If you subclass the original fields will be still stored in the original table, so references would stay valid.
If you want to monkey-patch an existing class, which is mostly not the recommendable dirty method, you could use contribute_to_class in some models.py file that will be loaded in an app after the one you want to modify:
models.py:
from django.db.models import CharField
from blog.models import Post
CharField(max_length="100").contribute_to_class(Post, 'new_field')
If you do it like this, you always have to bare the risk that your changes can clash with other pieces of code and that your code will be harder to maintain!

Is there a way to express Django admin settings inside the models, instead of admin.py?

Talking about Django 1.1.1. I thought at one time (0.96) the kinds of things put inside of the admin.py file were part of an inner class of the model.
There's a certain beauty in having all of this in one place. But I don't know if this change was out of necessity. Any compelling reasons one way or the other?
They took away that particular magic, but there is nothing to keep you from putting your admin.ModelAdmin subclass right after the models.Model subclass itself. I prefer keeping them together myself because it's less likely I'll forget to add a field to the list to show in the admin display.
Perhaps it would not be a good idea to have this stuff in the models anyway, since it would be excess information when using the site as a non-admin? (For performance reasons)
There isn't any way to express the admin options inside the model definition as an inner class in the latest version. But there is no reason why you can't put your ModelAdmin class right after your Model class in your models.py file. You can then just call your admin.site.register() right after your definition.
You may run into a problem with the register() being called more than once for a model, which will generate an error. models.py should only get loaded once though so this should work. If not, you can definitely declare your ModelAdmin class in models.py, and then put all your register() calls in admin.py.
A couple reasons that I can think of to put it them in admin.py are:
Convention -- seems like this is becoming a best practice.
Decoupling -- the admin definitions don't really have much to do with the model.
Cleanness -- probably no need to fill up your models.py file with stuff you aren't going to change much.
But if your models.py file isn't going to be very long I can see the attraction of having them right next to each other.
use class Admin inside your models as u use class Meta
and then define what u want