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)
Related
i want to use django signals to identify if a user is logged-in twice and if so, revoke his first session so that only one user session can be present at once.
i used the following example but it seems that my signals.py does not even gets reconcnized and i dont know why.
Example:
How to prevent multiple login in Django
accounts/signals.py
from django.contrib.auth import user_logged_in
from django.dispatch.dispatcher import receiver
from django.contrib.sessions.models import Session
from .models import UserSession
#receiver(user_logged_in)
def remove_other_sessions(sender, user, request, **kwargs):
# remove other sessions
Session.objects.filter(usersession__user=user).delete()
# save current session
request.session.save()
# create a link from the user to the current session (for later removal)
UserSession.objects.get_or_create(
user=user,
session=Session.objects.get(pk=request.session.session_key)
)
accounts/models.py
# Model to store the list of logged in users
class UserSession(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
session = models.OneToOneField(Session, on_delete=models.CASCADE)
accounts/apps.py
from django.apps import AppConfig
class AccountsConfig(AppConfig):
name = 'Accounts'
def ready(self):
import Accounts.signals
but for some reason nothing gets written onto the database for that table.
do i maybe miss something here, this is the very first time i get in touch with signals so i might missed something at the configuration.
Try this,
default_app_config = 'Accounts.apps.AccountsConfig'
Add this line in __init__.py file of your apps.py file directory.
I have a problem with duplicate signals. I have looked-up the relevant part of Django docs and a similar question on Stackoverflow but I still can't get it working right - i.e. the action that I have planned (creation on an ActivityLog entry) is actually happening 4 times :/
I have added the dispatch_uid and the problem still persists, so I guess I'm doing something wrong. Can you please hint me to the error?
Here's my code:
signals.py
from patient.models import Patient
from .models import ActivityLog
#receiver(pre_save, sender=Patient)
def create_new_patient(sender, instance, **kwargs):
ActivityLog.objects.create(
user=instance.created_by_user,
event='created a new patient',
patient_id=instance.patient_id
)
and this is it's usage in the patient.apps module:
from django.apps import AppConfig
from django.db.models.signals import pre_save
app_name = "patient"
class PatientConfig(AppConfig):
name = 'patient'
verbose_name = "Patients"
def ready(self):
from activity_logger.signals import create_new_patient
print('Patient APP is ready!')
pre_save.connect(create_new_patient, sender='patient.Patient', dispatch_uid='patient')
The print Patient APP is ready! does appear twice, and the object gets created 4 times, despite setting the dispatch_uid. What have I misunderstood?
The #receiver(Signal,...) decorator is a shortcut for Signal.connect(...), so you indeed register your create_new_patient handler twice (once thru #receiver when importing your signals module, the second time with pre_save.connect().
Solution : in your App.ready() method, you should just import your app's signal.py module. This will trigger the registration of the handlers decorated with #receiver.
I used the built-in login view that django makes but now I don't know how to set sessions when a user logs in. I was thinking of redirecting a user to a new view that would add these session variables but I don't see that as an ideal fix. Another question I have is: Can I use these session variables in my templates? If not, how would I get that data to the templates?
Also I am using Django 1.11 with python 2.7.
I figured out what I needed to do. You need to use signals. Essentially you just need to set a signal that once a user logs in, set the sessions.
Here is how it looks in my code:
#receiver(user_logged_in)
def sig_user_logged_in(sender, user, request, **kwargs):
request.session['isLoggedIn'] = True
request.session['isAdmin'] = user.is_superuser
request.session['team'] = user.teams
request.session['email'] = user.email
isLoggedIn = request.session.get('isLoggedIn',False)
isAdmin = request.session.get('isAdmin',False)
team =request.session.get('team','')
email = request.session.get('email','')
return render(
request,
'registration/login.html',
context = {'isLoggedIn':isLoggedIn,'isAdmin':isAdmin,'team':team,'email':email},
)
Make sure to have these imports:
from django.dispatch import receiver
from django.contrib.auth.signals import user_logged_in
Also if you were wondering which file I put this in, it was views.py
How to add the last_login_ip, when the user login if using rest-auth?
Befor ask the post I searched one post bellow:
How can I do my logic in `http://127.0.0.1:8000/rest-auth/login/` of `django-rest-auth`?
The answer is perfect for custom verify the login params.
But, how about after login, then add attribute to the User?
I mean, the answer is just for verify the data, I want to after user login success, I want to add the last_login_ip to the user instance.
EDIT
Please be attention, I know how to get the remote IP who visit my site. I mean I use the rest-auth to login, and customized LoginSerializer like the link. The link is for verify the login data, I can not to change the last_login_ip data in the LoginSerializer, I want when the user login success, then change the user's last_login_ip. but where to write my change last_login_ip code?
EDIT-2
I follow the #at14's advice, in the init.py (as the same level as apps.py):
default_app_config = '管理员后台.用户管理.qiyun_admin_usermanage.apps.QiyunAdminUsermanageConfig'
and in the apps.py:
from django.apps import AppConfig
class QiyunAdminUsermanageConfig(AppConfig):
name = 'qiyun_admin_usermanage'
def ready(self):
import 管理员后台.用户管理.qiyun_admin_usermanage.api.signals
There will get bellow error:
django.core.exceptions.ImproperlyConfigured: Cannot import 'qiyun_admin_usermanage'. Check that '管理员后台.用户管理.qiyun_admin_usermanage.apps.QiyunAdminUsermanageConfig.name' is correct.
and I also tried to comment the default_app_config = '管理员后台.用户管理.qiyun_admin_usermanage.apps.QiyunAdminUsermanageConfig' in the init.py, but still not work.
Use django's user logged in signal to save this information into the database.
In signals.py,
from django.contrib.auth.signals import user_logged_in
from django.dispatch import receiver
#receiver(user_logged_in)
def user_logged_in_callback(sender, user, request, **kwargs):
// Get the IP Address and save it
Read more about signals here.
Do pay attention on how to import signals in your app ready method
Make an apps.py (it might already exist) in your app directory,
from django.apps import AppConfig
class YourAppConfig(AppConfig):
name = '管理员后台.用户管理.qiyun_admin_usermanage'
def ready(self):
import 管理员后台.用户管理.qiyun_admin_usermanage.api.signals # noqa
In your apps init.py file,
default_app_config = '管理员后台.用户管理.qiyun_admin_usermanage.apps.QiyunAdminUsermanageConfig'
I'd like to show a notification to user with some stats (e.g how many items have been sold since last time he logged in)
#receiver(user_logged_in)
def notify_user_on_login(sender, request, user, **kwargs):
items = Item.objects.filter(status=Item.HISTORY_STATUS, seller=user, when_trading__gte=user.last_login)
However, in this signal last_login has already been updated.
According to the source at django.contib.auth django also connects signal with function that updates last_login:
user_logged_in.connect(update_last_login)
Is it possible to call my function BEFORE updating? Or get same result without adding custom field or doing some strange magic?
The last_login is also updated with a handler to that signal, which is surely registered and executed before yours. You might be able to solve your issue by moving your app over django.contrib.auth in INSTALLED_APPS.
Signal handlers depending on order doesn't seem like a good idea though. So I would probably replace Django's handler with your own:
from django.contrib.auth.models import update_last_login
def notify_user_on_login(user):
items = Item.objects.filter(status=Item.HISTORY_STATUS, seller=user, when_trading__gte=user.last_login)
#receiver(user_logged_in)
def after_user_logged_in(sender, user, **kwargs):
notify_user_on_login(user)
update_last_login(sender, user, **kwargs)
user_logged_in.disconnect(update_last_login)