No module named 'signals' in Django Project - python

I'm practice Django and I'm trying to make function
( Ready ) in the app.py and import
( users.signals ) into this function and I already used
pip install signals to install signals package and didn't solve it yet.
apps.py
from django.apps import AppConfig
class UsersConfig(AppConfig):
name = 'users'
def ready(self):
import users.signals
signals.py
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, **kwargs):
if created:
Profile.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
instance.profile.save()
No module named 'signals'

Related

Django: How to delete a group which is related to a team?

I want to extend Django's group model. To do so I've created a Team class, which references the group model with a OneToOne field. Create and update work as expected, but I fail to delete the team.
# teamapp/models.py
from django.db import models
from rules.contrib.models import RulesModel
from django.contrib.auth.models import Group
class Team(RulesModel):
group = models.OneToOneField(
Group,
on_delete=models.CASCADE,
primary_key=True,
)
name = models.CharField(max_length=80)
def save(self, *args, **kwargs):
self.update_or_create_group()
return super().save(*args, **kwargs)
def update_or_create_group(self, *args, **kwargs):
team_group, _ = Group.objects.update_or_create(
id=self.pk,
defaults={"name": self.name},
)
self.group = team_group
# teamapp/signals.py
from django.db.models.signals import post_delete
from django.dispatch import receiver
from django.db import transaction
from django.contrib.auth.models import Group
from teamapp.models import Team
#receiver(post_delete, sender=Team)
def delete_group(sender, instance, **kwargs):
# TODO: Use celery for async operation: https://docs.djangoproject.com/en/3.2/topics/db/transactions/
transaction.on_commit(lambda: delete_group(instance))
def delete_group(team_instance):
Group.objects.filter(id=team_instance.group.id).delete()
Somehow the signal doesn't trigger. Is there an other way?
Not sure if this is an acceptable way, but I forgot to load the signal. So I've loaded it though the apps.py file.
# teamapp/apps.py
from django.apps import AppConfig
class TeamappConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "teamapp"
verbose_name = "Team"
def ready(self):
import teamapp.signals

Django - Is there any way to get the current logged user in the signals.py file of my proyect?

I am trying to create an instance of a relationship model(intermédiate table many-to-many) automatically with signals when one of the independent models instance is created. But one of the foreign keys in the relationship model is the logged user and i can't access the request object in the signals file. maybe there is another without signals but idk. Any suggestions are appreciated. UserAccount is a custom user model. this is the code
models.py
from datetime import datetime
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from apps.accounts.models import UserAccount
class Patient(models.Model):
name = models.CharField(max_length=50)
userAccount = models.ManyToManyField('accounts.UserAccount', through='Therapy')
class Therapy(models.Model):
patient = models.ForeignKey(Patient, on_delete=models.CASCADE)
userAccount = models.ForeignKey(UserAccount, on_delete=models.CASCADE)
createdDate = models.DateTimeField(auto_now_add=True)
signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Patient, Therapy
#receiver(post_save, sender=Patient)
def create_therapy(sender, instance, created, **kwargs):
if created:
Therapy.objects.create(patient=instance, userAccount=request.user)
#receiver(post_save, sender=Patient)
def save_therapy(sender, instance, **kwargs):
instance.patient.save()
Try with:
import getpass
current_logged_in_user = getpass.getuser()
you have to install getpass before, in your command line run:
pip install getpass4
This worked for me:
if created:
import inspect
request = None
for fr in inspect.stack():
if fr[3] == 'get_response':
request = fr[0].f_locals['request']
break
current_logged_in_user = request.user

Django signals not working when placed outside models.py

I'm trying to print some text after Django model in an app has been saved.
I have created a signal for that in a signals.py file in the same application.
However, it's not working as expected (i.e., the function is not being called and text is not being printed)
But if I place the receiver function in the models.py file just below the model that I created, it's working fine (i.e., the function is being called and text has been printed)
I have gone through the documentation to check if there is any need to place the signals in a specific file or location. It looks like there isn't any such restriction.
https://docs.djangoproject.com/en/3.0/topics/signals/#django.dispatch.receiver
Why is this behaving differently if there is no such restriction?
signals.py:
from django.db.models.signals import post_save
from django.dispatch import receiver
from aws_envs.models import UserStack
#receiver(post_save, sender=UserStack)
def create_user_stack(sender, **kwargs):
print("creating user stack now")
models.py:
class UserStack(BaseModel):
name = models.CharField(max_length=50)
email = models.EmailField(unique=True, max_length=50, blank=False)
enabled = models.BooleanField(default=True)
def save(self, *args, **kwargs):
print(f"Creating stack with data: {self.name, self.email}")
super(UserStack, self).save(*args, **kwargs)
def __str__(self):
return self.name, self.email
in INSTALLED_APPS you should register like this:
'post.apps.PostConfig'
I.e. in settings.py replace
INSTALLED_APPS = (
'...',
'post,
)
with
INSTALLED_APPS = (
'...',
'post.apps.PostConfig',
)
in apps.py you shoud add these:
from django.apps import AppConfig
class postConfig(AppConfig):
name = 'post'
def ready(self):
# signals are imported, so that they are defined and can be used
import post.signals
created a file in app's folder
# post/signals.py
from django.dispatch import receiver
from django.db.models.signals import post_save
from post.models import Post
def send():
print("send email!")
#receiver(post_save, sender=Post, dispatch_uid='Post_post_save')
def send_email(instance, **kwargs):
send()

Django signals not working on usercreation

I created a signals supposed to create a profile for each created users in my signals.py file but it's not working. I've tried to check if there's an error with the command python manage.py check, but that seems not to work as well.
models.py
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
profile_pic = models.ImageField(default='default.jpg', upload_to='profile_pics')
def __str__(self):
return f"{self.user.username}'s profile "
signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import User
from .models import Profile
#receiver(post_save, sender=User)
def create_profile(sender, created, instance, **kwargs):
if created:
Profle.instance.create(user=instance)
#receiver(post_save, sender=User)
def create_profile(sender, instance, **kwargs):
instance.profile.save()
apps.py
from django.apps import AppConfig
class UsersConfig(AppConfig):
name = 'users'
def ready(self):
import users.signals
What am I doing wrong?
The order of parameters in your signal handler is wrong, change:
def create_profile(sender, created, instance, **kwargs):
to:
def create_profile(sender, instance, created, **kwargs):
Check the post_signal documentation for further details.
The problem is from how i installed the users app in the settings.py file in the main project directory.
i used :
INSTALLED_APPS = [
'users',
]
**instead of **
INSTALLED_APPS = [
'users.apps.UsersConfig',
]

Add field to django auth user?

I am trying to add a new field to the built in auth user. Here is my code
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth import get_user_model
from django.contrib.postgres.fields import ArrayField
class Profile(models.Model):
user = models.OneToOneField(get_user_model(), on_delete=models.CASCADE)
newField = ArrayField(models.CharField(max_length=16))
#receiver(post_save, sender=get_user_model())
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
#receiver(post_save, sender=get_user_model())
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
And in my view I have the following:
current_user = User.objects.get(username=request.user)
current_user.save()
And i am getting the error
Exception Type: RelatedObjectDoesNotExist
Exception Value: User has no profile.
Am i doing this wrong? I creates a profile table in the db but that didnt seem to be the issue
Its maybe because you are creating user and triggering both signal functions at a time. So maybe you can try like this:
#receiver(post_save, sender=get_user_model())
def save_user_profile(sender, instance, created, **kwargs):
if not created:
instance.profile.save()
Or better,combine both signals into one:
#receiver(post_save, sender=get_user_model())
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
else:
instance.profile.save()
The reason is your are defining two signals with one sender. So when the user is saved, both signals will be triggered, But the second is faster and will execute right away. And because for that user no profile is created, it throws an error. Because the profile object for that user by first signal isn't created yet.
#receiver(post_save, sender=get_user_model())
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
Note no need to perform instance.profile.save() here.

Categories