Django logged in user in models.py or signal handler - django

Is there a way to access the request.user in either models.py or in a signal handler?
I'm using the m2m_changed signal and defining it in my models.py - I'd like to access the logged in user there.
Is there a way to do this?

I'm assuming user making a change is not necessarily record owner or author. This means model lookups are useless and you need to pass this data via signal.
Good way to do this is to create custom signal which has current user as one of attributes and emit it in view code when the data is being saved.

Related

Submit forms in django without refreshing the page

Okay, first of all, I know that there are a lot of videos and tutorials out there to help with the question I have raised. However, my case is a little different than the usual. So, basically, I am trying to build out a chat app on Django. For this I am planning to save the messages that the user wants to send in the database and then render them on screen. Now, in order to send this data to the server, I wish to use Ajax as it would prevent page reload and thus make for a much smoother UX. However, that raises an issue. The issue is that how do I keep track of the fact that which room/ chat is the message coming from and which user sent it? The obvious solution that comes to mind is the create a hidden field inside if my form and then pass in the room details of it through that hidden field. But won't that be highly insecure as the data could be subject to change, allowing users to send messages from a chat they have access to, to a chat they don't have access to? The username part can still be managed using request.user. The trouble is arising only with the tracking room details part.
Any help/ideas are welcome.
Thanks!
First of all take a look at Django Unicorn:
https://www.django-unicorn.com/
This might be the perfect fit for this kind of application.
But won't that be highly insecure as the data could be subject to change, allowing users to send messages from a chat they have access to, to a chat they don't have access to?
As Abdul Aziz Barkat already pointet out is true for all kind of form submission. You have to check in your code if the user is allowed to post to/from a room and to a person. This can be done in the forms clean() method where you can raise errors like PermissionDenied.
Edit
response to your first comment:
You need to keep track permissions of the chat. e.g. which users are allowed to write in this chat and those that are allowed to read the chat
class Chat(models.Model):
# your generic chat class
# ...
write = models.ManyToManyField(User, blank=True, related_name="users_write_access")
read = models.ManyToManyField(User, blank=True, related_name="user_read_access")
As soon as a user becomes a member of a chat add them to the write and read field.
If a user tries to send a message to a chat check if he's a member of the write list. e.g.
from django.shortcuts import get_object_or_404
from django.contrib.auth import PermissionDenied
def send_message_to_chat(request, chat_id):
chat = get_object_or_404(Chat, pk=chat_id)
if request.user not in chat.write.all():
raise PermissionDenied("You are not allowed to write in this chat...")
# continue with your code to send messages
to something similar for read access. I hope this helps

Creating an employee for each user record

I want to create a record in employee model each time I create an user. Any suggestions about how to do that?
If you mean the Django-supplied User model, then probably best to use pre-save or post-save signals.
If you mean your own model, you can subclass its save method.

Django send email to the user when a specific field on a model has bean changed

I want to send an email to a user on model change.
Here is what I have : I have a model called package containing a field status and a field owner , I want to send an email to the owner of the package when the status is changed.
Is there a way to do so ?
Thank you
Signals might help you out.
Think of Signal methods as code that is always executed before or after an operation on a model; e.g, a pre_save() signal is called just before a record is saved to database, post_delete() is called just after a record is deleted from the database.
Implement a pre_save() signal on the model and get the value of status field from the database before saving. Check if this previous value is different from the one for the corresponding status field in update_fields. If so, email the user.
Here are the docs for pre_save()
and Signals.
Here's a tutorial I followed while learning Signals:
How to Create Django Signals
- SimpleIsBetterThanComplex.
Hope this helps :)
When the event of changing status is triggered, send the email to the owner.
Documentation: https://docs.djangoproject.com/en/1.11/topics/email/
Or if your prefer the built-in notification:How to use django-notification to inform a user when somebody comments on their post

Sending emails after updating the model from the admin page (Django)

Hello I want to know if there is a way to send an email to a user upon someone updating certain fields in the Django admin page being updated. Is there a way to do this? I already have an email being sent upon the forms completion, but I need to send more emails once one of the users updates through the admin page.
I have taken a look at the post_save, model_save and save_formset methods, but I did not feel that they were what I was looking for.
Try overriding the ModelAdmin.save_model method. I think it has hooks for all the information you require.
The change variable lets you distinguish between a user adding or changing the model instance.
form.changed_data gives you a list of the names of the fields which have changed, which lets you determine whether or not to send the email.
Finally request.user identifies the user which made the changes.
You need django.db.models.signals.post_save signal. It is sanding after the model has been saved.
def my_callback(sender, **kwargs):
# Your specific logic here
pass
post_syncdb.connect(my_callback, sender=yourapp.models.TheModel)
Arguments sent with this signal:
sender:
The model class.
instance:
The actual instance being saved.
created
A boolean; True if a new record was created.
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 you need only callback and sender.

How to get session from signal handler in Django

I'm implementing a simple referral system. I have middleware which sets a session variable identifying the referring user. I have a model which ties a referring user to the referred user. I'm trying to use the post_save signal from the User object to populate this model. How do I access the session object from within the post_save signal handler?
There is not way without using a thread specific global variable.
But I'm not sure you need to. For my referral and invite system I just have the user register as normal and after the user has been created, get the referral out of the session. In almost all situations it will still be the same session.
If there is something about your session that prevents that, I would instead add it to the create user form.
You may find useful documentation on using sessions out of views.