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
Related
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
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()
I have a model SessionCategory which is similar to the following:
from django.db import models
from django.utils.text import slugify
class SessionCategory(models.Model):
name = models.CharField(max_length=255, unique=True)
name_slug = models.CharField(max_length=255, null=True)
def save(self, *args, **kwargs):
if not self.name_slug:
self.name_slug = slugify(self.name)
super().save(*args, **kwargs)
So the name_slug field, which I'd like to add, is a slugified version of the name field.
I've run the following data migration:
from __future__ import unicode_literals
from django.db import migrations, models
def generate_name_slugs(apps, schema_editor):
SessionType = apps.get_model('lucy_web', 'SessionType')
for session_type in SessionType.objects.all():
session_type.save()
class Migration(migrations.Migration):
dependencies = [
('lucy_web', '0163_auto_20180627_1309'),
]
operations = [
migrations.AddField(
model_name='sessioncategory',
name='name_slug',
field=models.CharField(max_length=255, null=True),
),
migrations.RunPython(
generate_name_slugs,
reverse_code=migrations.RunPython.noop),
]
However, if I check the database afterward, the name_slug fields are all null:
I've also reversed the migration and re-run it setting a trace (import ipdb; ipdb.set_trace()) in the overridden save() method, but it didn't cause Python to drop into the debugger, confirming that that method is not called.
Why is the overridden save() method not getting called? Do I have to replicate the code in the generate_name_slugs function?
This should help for SessionType... SessionCategory can be modified the same way...
def generate_name_slugs(apps, schema_editor):
import lucy_web.models as m
for session_type in m.SessionType.objects.all():
session_type.save()
I am trying to create a model in which I have a case_id field. This field should be auto incrementing. But my case_id value should be in the format shown,
case_id=FAS150001 (This should be the first value)
class InformationRequest(models.Model):
"""Model to track information"""
case_id = models.CharField(max_length=50)
user = models.ForeignKey(User)
information = models.TextField()
How can I do this?
Charfields cannot be auto-incremented.
But Django signals can help you to simulate this behavior. You could do a pre-save or post-save signal for make it, for example:
from django.db.models.signals import pre_save
from django.dispatch import receiver
from myapp.models import InformationRequest
#receiver(pre_save, sender=InformationRequest)
def my_handler(sender, instance=None, **kwargs):
# Compute case_id, ex:
# instance.case_id = increment_case_id()
I need to create an instance of my model every time a new group has been created in the admin panel.
I read some information about signals, but i can't figured it out at all.
Thank you very much
models.py with your model:
from django.db import models
from django.contrib.auth.models import Group
from django.db.models.signals import post_save
class YourModel(models.Model):
name = models.CharField('name', max_length=50)
group = models.ForeignKey(Group)
# ...
#classmethod
def create_after_group(cls, sender, instance, created, **kwargs):
if created:
group_created = instance
m = cls(name="Some name", group=group_created)
m.save()
post_save.connect(YourModel.create_after_group, sender=Group)