I have a model.that I need to if any model with specific field created in database.send a Email to user for notify.I did some search too many apps are there for handling the notify. thats not my concern .I dont know how deploy this structure.any guide or example for this.for example :
if x = book.objects.create(title="book1") :
print("the book created")
if this action happend do something.
If you need to monitor object creation globally the best thing to use is signals
Like so:
from .models import Book
from django.db.models.signals import post_save
def book_created(sender, instance, created, **kwargs):
if created and instance.title == 'book1':
#logic here
post_save.connect(save_profile, sender=Book)
you need to stick that post_save.connect() function somewhere where it will be evaluated when the app is run, you can use app_dir/app.py for instance.
Related
I am using django with python. I am trying to update the model whenever a field is updated, in this case because i have a lambda function in the cloud, i want when a postgres query update an instance of the model, during the update action, update the age of the Person model below:
data
Contact table
id = 1
name = 'john'
age = 38
sql
UPDATE contacts_contact SET name = 'jane' where id = '1'; # this works fine
now i want to make sure that when the name is changed to jane as above, that the age update automatically in django with the override method
django
class Contact(models.Model):
..
name = models.CharField()
age = models.IntegerField()
def update(self, *args, **kwargs):
if self.age:
self.age = 25
super().update(*args, **kwargs) # i tried this
super(Contact, self).update(*args, **kwargs) # i tried this too
both update methods i tried above do not update the age of the person regardless of the fact that the sql query update worked
is there something that i am missing?
PS: I want to update that field specifically in django, not in the sql query
"I am using django with python. I am trying to update the model whenever a field is updated" if this is the case django signals can help you, in-fact they are built for this purpose only.
follow the below to steps to enable the django-signals for your models.
Inside your_app/app.py you can find the snippets as below. if not paste the same and modify it with your app name. here you're just importing the signals(contents in your_app/signal.py)
from django.apps import AppConfig
class YourAppConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'your_app'
verbose_name = 'Your App'
def ready(self):
import your_app.signals
Inside your_app/signals.py paste the contents below in it. modify it with your own model name. for now I'll use your Contact model.
from django.db.models.signals import post_save
from your_app.models import Contact
from django.dispatch import receiver
#receiver(post_save, sender=Contact)
def create_user(sender, instance, created, **kwargs):
print(sender)
print(instance)
print(kwargs)
if created:
print('Hurray its created', created)
here you can use post_save signal. Django includes a “signal dispatcher” which helps decoupled applications get notified when actions occur elsewhere in the framework. In a nutshell, signals allow certain senders to notify a set of receivers that some action has taken place.
whenever you call .save() method of Contact model(create/update). for example -
c = Contact(name='zzz', age=20)
c.save()
now this will make the post_save signal to get notified about the changes, you can verify the same in your create_user() method print statements. from here you can do whatever you want with your model.
you can refer more about post_save signals here https://docs.djangoproject.com/en/4.0/ref/signals/#post-save
I have a django server with an admin panel.
Different users make changes there and this is saved via auditlog in the database and displayed in the "history".
But there are situations when a user enters under the account of another user and makes changes on his behalf.
In order to identify from which device this or that change was made, it was a nice decision to also record data about the IP of the user from whom the change was made, and his unique device number.
By overloading several methods in the "AuditlogMiddleware" class, I got the desired result via "uuid.UUID(int=uuid.getnode())".
(Tested locally, because the prod server is heavily loaded and there is no way to do test committees)
from __future__ import unicode_literals
import threading
import time
from auditlog.middleware import AuditlogMiddleware
threadlocal = threading.local()
class ExtendedAuditlogMiddleware(AuditlogMiddleware):
def process_request(self, request):
threadlocal.auditlog = {
'signal_duid': (self.__class__, time.time()),
'remote_addr': request.META.get('REMOTE_ADDR'),
}
super(ExtendedAuditlogMiddleware, self).process_request(request)
**#changes here
import uuid
threadlocal.auditlog['additional_data'] = str(uuid.UUID(int=uuid.getnode()))+" | "+request.META["USERNAME"]**
# #staticmethod
def set_actor(self, user, sender, instance, signal_duid, **kwargs):
super(ExtendedAuditlogMiddleware, self).set_actor(user, sender, instance, signal_duid, **kwargs)
**#changes here
instance.additional_data = threadlocal.auditlog['additional_data']**
But the problem is that I think I get the UUID not of the user, but of the server, because there is no access to the user, i guess. I couldn't find the information, and I couldn't come up with my own solution either.
Question - is it even possible to get information from the server about django admin users' devices??
If not, what can i use instead of UUID to identify which device was used while making changes in django admin panel??
Thank you all in advance!
try to use javascript in side of your template to send this info thrugh
I want to execute a function after a record inserted to database using django-admin panel .
I have a product table , i want to send notification to users when a record inserted in database by django admin panel . i know how to send notification to users , but i dont know where to put my code .
any suggestion will be helpfull .
How can i execute a function to notify user after my record inserted ?
here is my code to execute after record inserted :
from fcm_django.models import FCMDevice
device = FCMDevice.objects.all()
device.send_message(title="Title", body="Message", icon=..., data={"test": "test"})
i searched alot but not found anything usefull .
thanks to this great communtiy .
You can modify save method on your product model
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
device = FCMDevice.objects.all()
device.send_message(title="Title", body="Message", icon=..., data={"test": "test"})
Well, it will send the notification every time the instance is saved (not only when it was added in django admin panel).
You need to use the Django model post_save signals to achieve this. This signal receiver can be placed in the same place where the model is
class FCMDevice(models.Model):
...
#receiver(post_save, sender=FCMDevice)
def notify_users(sender, instance, **kwargs):
# your logic goes here
# instance is referred to currently inserted row
pass
You might wanna check post_save signal. From the docs:
Like pre_save, but sent at the end of the save() method.
url: https://docs.djangoproject.com/en/2.1/ref/signals/#post-save
django-version: 1.7+
I'm using Django (with python-social-auth) to authenticate users for an internal student information system.
We currently have an external SQL table, that keeps track of whether a user is: an admin, staff member, or student, based on their Google Apps email address.
Current post_save function
#receiver(post_save, sender=User)
def create_student_or_staff(sender, instance, created, **kwargs):
if created:
try:
state = UserState.objects.get(
email=instance.email
)
except UserState.DoesNotExist:
# if exception is raised here, user is not created but site crashes
# if no exception is raised, a user is created but no admin, staff or student instance
pass
if state.staff:
if state.is_admin:
Admin.objects.create(
user=instance
)
else:
Staff.objects.create(
user=instance
)
else:
class_instance = None
if state.year and state.band and state.set:
class_model = apps.get_model('class_groups.ClassGroup')
class_instance = class_model.objects.get(
year=state.year,
band=state.band,
set=state.set
)
Student.objects.create(
user=instance,
class_group=class_instance
)
When a user first attempts to login, I want to be able to check against that database to see if they meet any of the criteria.
Currently, using the post_save signal for the user (I've also tried to use pre_save but no dice) to somehow halt the creation of a Django user object if they are not on the UserState table.
Is this possible at all? The only way I can halt the creation of a user instance currently is by raising an exception during the post_save, which isn't ideal of course.
Sorry for the broad question, if you need any specifics please let me know. Thanks in advance!
The best option i think is use the user_pass_test function or use the UserPassTestMixin for class base views.
Ended up adding a new pipeline for python-social that checks if the incoming email address is already in the UserState database.
Pipeline added after the social details are retrieved.
settings.py
# adding all the pipelines in for the time being, can adjust later
SOCIAL_AUTH_PIPELINE = (
'social.pipeline.social_auth.social_details',
# custom pipeline
'sis_users.pipeline.user_state_exists',
'social.pipeline.user.user_details',
...
)
pipeline.py
def user_state_exists(backend, details, response, *args, **kwargs):
email = details['email']
try:
UserState.objects.get(
email=email
)
except UserState.DoesNotExist:
raise UserStateDoesNotExistException(backend)
exceptions.py
from social_core.exceptions import AuthException
class UserStateDoesNotExistException(AuthException):
def __str__(self):
return "You must be an administrator, staff member or a student to sign in. Please contact the school for more assistance."
Thanks for all the suggestions!
I'm picking up on a code which should send a signal every time a user logs in. Thats not happening though. The function get_create_stripe() isnt getting called when the user logs in.
Anyone can tell whats wrong?
I'm working in Django 1.8 and the whole code is here.
Gist about the code: This code is part of an e-commerce site which users stripe as its payment gateway. Intent is, every time user logs in, we create a new stripe id or return an existing one.
Is it because this function is not in models.py? This is written to a file 'signals.py' and I'm not quite sure how Django should understand to call get_create_stripe() from a signal call in this file. Is it so?
import stripe
from django.conf import settings
from django.contrib.auth.signals import user_logged_in
from .models import UserStripe
stripe.api_key = settings.STRIPE_SECRET_KEY
def get_create_stripe(sender, user, *args, **kwargs):
new_user_stripe, created = UserStripe.objects.get_or_create(user=user)
print "hello"
if created:
customer = stripe.Customer.create(
email = str(user.email)
)
print customer
new_user_stripe.stripe_id = customer.id
new_user_stripe.save()
user_logged_in(get_create_stripe)
You need to connect your signal method to the signal.
Something like
from django.dispatch import receiver
from django.contrib.auth.signals import user_logged_in
#receiver(user_logged_in, sender=UserStripe)
def get_create_stripe(sender, user, *args, **kwargs):
EDIT: Also, what is this:
user_logged_in(get_create_stripe)
That is not how signals work. Either you do what I wrote above, or do this:
user_logged_in.connect(get_create_stripe)