Updating when database has changed in Django - django

I have many records in my database that are displayed on a screen. However, the records are user generated and sometimes have to be removed. Each record has a show field which is initially always set to true. When we get content that has to be removed a human will set it to false in the Django admin interface. When this happens, we need the bad content to be removed from the screen. So my question is, in the Django interface, what is the way to tell when a record has been updated and do something in response to this change?

You should read about signals:
An Idea on how doing this:
from django.core.signals import post_save
from django.dispatch import receiver
#receiver(post_save, sender=MyModel)
def my_handler(sender, instance, created, raw, **kwargs):
if created: # True for save, False for update
...
I think this could help you tell when the record its being updated and when you can do something about it.
But if the user seeing the records wont have to refresh the page so the record is hidden, then you could use websockets to receive that information your signal sent. Or you can just do ajax requests every 20-30 seconds to check all the records and discovery which one is hidden, or you can check a list of latest hidden records that your signal will populate.
Anyway, there is different ways of doing this.

Related

Collect data from multiple Django signals in session or cache

I have a view in views.py that hits multiple database models. Each model has its own signals registered with it (pre_save, post_save, post_delete, ...etc). Each signal collects the changes in data for each model.
Now, I want to collect all those changes to use them somehow at the end of my view. So, I though about saving such data temporarily in the user's session or cache to retrieve them just at the ned of my view, but unfortunately the signal functions doesn't take request parameter with it.
So, how can I do such?

RelatedObjectDoesNotExist at /login/ while running the server locally

I using One To One field in Django to save some extra information about user but even afte migrating i got the issue which i mentioned in title
my models.py
the issue I got
issue while running server
please help if you can
The error you are getting:
User has no profile
Simply means what it says, meaning the particular User instance you are dealing with has no related Profile. Now you might be wondering why not, but that is because a User record can perfectly exist without a 'Profile' relation, the constraint only applies to your profiles, which cannot be created without a corresponding user record.
So if you have somehow tried linking the user to a certain profile, that means the code that is supposed to make that happen isn't doing so and from what I got from the images, you're using signals for that. But I wouldn't recommend doing so, not because signals are generally bad, but because in this case its sorta overkill, and it spreads your code too much.
What I'd suggest/recommend is to add the logic to create profile in the User creation form.
Your problem is probably because the user does not have an associated profile in the DB.
Even though there is an OneToOne relation there doesn't a guarantee. that a user will have a profile.
So you probably need to create a profile for that user.
Also if you want to extend the user model, Ill recommend that you check out this. It contains more ways to achieve what you are looking for
profile doesnt get created automatically ,you need either to add it manually or use signals so that every time a user is created a profile also is created,
if you have a profile model lets say you named it Profile
create a signals.py and add this to it:
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile
#receiver(post_save, sender=User)
def create_profile(sender, instance, created, *args, **kwargs):
if created:
Profile.objects.create(user=instance)
If you're adding blank=True, then why are you adding default=''
If you want profile picture to be mandatory, remove blank=True

Django TastyPie, how to trigger action after POST with ManyToMany fields?

I have a REST API built using Django and TastyPie. My goal is to add a task to my job queue when new data is POSTed to a particular model.
I was going to hook into post_save and trigger then but the model contains ManyToMany relationships and so the post_save is triggered before the m2m relationships update and hooking into the m2m_changed signal seems messy. I get multiple signal events and my code will need to check the instance after each one and try and determine if it's ready to trigger the event. Some of the ManyToMany fields can be Null so when I get an m2m_changed signal I don't really know for sure if it's done saving.
Is there a correct way to do this? Does TastyPie allow me to hook into the POST event and do something at the end? All the things I have found point me at post_save events to do this.
Does Django have a way to signal me when all m2m updates for a given model instance are completed?
If you are using POST, then obj_update() does not appear to work for me. What did work was using obj_create() as follows:
class Resource(ModelResource):
def obj_create(self,bundle,**kwargs):
bundle = super(Resource,self).obj_create(bundle,**kwargs)
# Add code here
return bundle
One thing to note is that request is not included. I tried that and it gave me an error.
You should be able to override the obj_update method
class Resource(ModelResource):
def obj_update(self, bundle, request, **kwargs):
bundle = super(Resource, self).obj_update(bundle, **kwargs)
# queue your task here
return bundle

Django testing: TemplateDoesNotExist when loading fixtures. Why?

I have an automatic welcome message generated from template, which is sent whenever a new user is created (through a post_save signal for the User model). Everything works as it should, except when I run manage.py test.
Django keeps complaining:
Problem installing fixture '.../lib/python2.7/site-packages/django/contrib/auth/fixtures/context-processors-users.xml
...
TemplateDoesNotExist users/email_welcome.html
when trying to load the django.contrib.auth fixtures for testing.
Why is it so? Are the template loaders not present when loading fixtures? What could be a solution to this?
I don't know why there is a problem with this template (it works for me), but probably during fixtures loading you don't want to generate this email. In this situation you can use raw argument wich is sent with signal. From Django docs about raw:
A boolean; True if the model is saved exactly as presented (i.e. when
loading a fixture). One should not query/modify other records in the
database as the database might not be in a consistent state yet.
So your code should look like this:
#receiver(post_save, sender=User)
def generate_email(sender, instance, created, raw, **kwargs):
if not raw:
# generate email from template

Django switch database dynamically

I'd like to switch databases upon user login. I've created this login signal.. but it doesn't work
from django.dispatch import receiver
from django.contrib.auth.signals import user_logged_in
from django.db import connections
#receiver(user_logged_in)
def db_switch(sender, **kwargs):
user_db = 'userdb_%s' % kwargs['user'].username
cursor = connections[user_db].cursor()
The databases are defined in settings.py. Do I have to make this cursor global? Or is this all the way wrong way of doing it?
Thanks!
It's the wrong way of doing it.
Honestly I don't think there is a straightforward, stable way of doing this in Django. It's just not designed for it.
Instead, I'd set up a settings_username.py file for each user, which specifies a secondary database called personal or something. Then, after logging, have them redirect to a new domain, like username.example.com, which uses a unique .wsgi file that pulls in the settingsusername.py file.
Now, as far as the system is concerned, each website is totally separate and unique to that user. Just make sure to set the session cookie to example.com so that they're still logged in when they go to their user website.