Wednesday, January 6, 2016

Re: Working with Django signals

Hi luisza

I've choose work overriding the  save() method of the  AbstractUser class, instead of apply the  post_save() signal to the  create_profile_for_new_use function.

According to the prevouos mentioned, my  User MedicalProfilePatientProfile y PhisiotherapystProfile models stayed so:

from __future__ import unicode_literals  from django.conf import settings  from django.contrib.auth.models import AbstractUser  from django.db import models  from django.template.defaultfilters import slugify  from django.dispatch import receiver  from django.db.models.signals import post_save    class User(AbstractUser):      is_medical = models.BooleanField(default=False)      is_physiotherapist = models.BooleanField(default=False)      is_patient = models.BooleanField(default=False)      slug = models.SlugField(max_length=100, blank=True)      photo = models.ImageField(upload_to='avatars', null = True, blank = True)        def save(self, *args, **kwargs):          user = super(User, self).save( *args, **kwargs)            # Creating and user with medical, patient and physiotherapist profiles          if self.is_medical and not MedicalProfile.objects.filter(user=self).exists()\                  and self.is_patient and not PatientProfile.objects.filter(user=self).exists()\                  and self.is_physiotherapist and not PhysiotherapistProfile.objects.filter(user=self).exists():                medical_profile=MedicalProfile(user=self).save()              patient_profile=PatientProfile(user=self).save()              physiotherapist_profile=PhysiotherapistProfile(user=self).save()              #profile.save()            # Creating and user with medical and patient profiles          elif self.is_medical and not MedicalProfile.objects.filter(user=self).exists()\              and self.is_patient and not PatientProfile.objects.filter(user=self).exists():                medical_profile=MedicalProfile(user=self).save()              patient_profile=PatientProfile(user=self).save()            # Creating and user with medical and physiotherapist profiles          elif self.is_medical and not MedicalProfile.objects.filter(user=self).exists()\              and self.is_physiotherapist and not PhysiotherapistProfile.objects.filter(user=self).exists():                medical_profile=MedicalProfile(user=self).save()              physiotherapist_profile=PhysiotherapistProfile(user=self).save()            # Creating and user with physiotherapist and patient profiles          elif self.is_physiotherapist and not PhysiotherapistProfile.objects.filter(user=self).exists()\              and self.is_patient and not PatientProfile.objects.filter(user=self).exists():                physiotherapist_profile = PhysiotherapistProfile(user=self).save()              patient_profile = PatientProfile(user=self).save()            # Creating and user with medical profile          elif self.is_medical and not MedicalProfile.objects.filter(user=self).exists():              profile = MedicalProfile(user=self)              profile.save()            # Creating and user with patient profile          elif self.is_patient and not PatientProfile.objects.filter(user=self).exists():              profile = PatientProfile(user=self)              profile.save()            # Creating and user with physiotherapist profiles          elif self.is_physiotherapist and not PhysiotherapistProfile.objects.filter(user=self).exists():              profile = PhysiotherapistProfile(user=self)              profile.save()            # We get the profiles user according with their type      def get_medical_profile(self):          medical_profile = None          if hasattr(self, 'medicalprofile'):              medical_profile=self.medicalprofile          return medical_profile        def get_patient_profile(self):          patient_profile = None          if hasattr(self, 'patientprofile'):              patient_profile = self.patientprofile          return patient_profile        def get_physiotherapist_profile(self):          physiotherapist_profile = None          if hasattr(self, 'physiotherapistprofile'):              physiotherapist_profile = self.physiotherapistprofile          return physiotherapist_profile        # We redefine the attributes (create db_table attribute) in class Meta to say to Django      # that users will save in the same table that the Django default user model      # https://github.com/django/django/blob/master/django/contrib/auth/models.py#L343      class Meta:            db_table = 'auth_user'    class MedicalProfile(models.Model):      user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)      #active = models.BooleanField(default=True)      name = models.CharField(max_length=64)      class PatientProfile(models.Model):      user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)      #active = models.BooleanField(default=True)      name = models.CharField(max_length=64)      class PhysiotherapistProfile(models.Model):      user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)      #active = models.BooleanField(default=True)      name = models.CharField(max_length=64)    # Enter the username as slug field  @receiver(post_save, sender = settings.AUTH_USER_MODEL)  def post_save_user(sender, instance, **kwargs):      slug = slugify(instance.username)      User.objects.filter(pk=instance.pk).update(slug=slug)


Of this way, is possible create an user which have all the combinations possible (medical, physiotherapist, patient)

Thanks for the recommendations :)

On Thursday, December 31, 2015 at 12:14:06 PM UTC-5, luisza14 wrote:
I suggest you to change the user creation form to set the three attributes that you need (Is medical, is physuitherapist, is patient), so in the first form (when you create the user) you will have usernarme, password, Is_medical, is_physuitherapist, is_patient.

Take a look
Or extends admin class in save_model function.

2015-12-30 17:14 GMT-06:00 Bernardo Garcia <boti...@gmail.com>:

I have a custom users schema in Django for work with roles or users type, creating an application named userprofile which will be or will setup my custom user model.

In my settings.py I have the following configuration:

INSTALLED_APPS = [          ...      'userprofile',  ]  #Custom model Users  AUTH_USER_MODEL = 'userprofile.User'


I customize my User class (userprofile/models.py) that inherit of the AbstractUser class for add some fields to my User model due to my requirements demanded me.

I also create these another models for roles/profile users (MedicalProfile, PatientProfile, PhysiotherapistProfile) with their own fields or attributes


In addition MedicalProfile, PatientProfile, PhysiotherapistProfile have a OneToOneField relationship with my custom model/class User so:


from __future__ import unicode_literals    from django.conf import settings  from django.contrib.auth.models import AbstractUser  from django.db import models    #from django.contrib.auth import get_user_model      from django.dispatch import receiver  from django.db.models.signals import post_save      # Extending Django's default User  # https://docs.djangoproject.com/en/1.9/topics/auth/customizing/#extending-django-s-default-user  # We inherit from AbstractUser class to add some fields/attibutes to our user model  # https://github.com/django/django/blob/master/django/contrib/auth/models.py#L297  # Differentes between AbstractUser and AbstractBaseUser  # http://stackoverflow.com/questions/21514354/difference-between-abstractuser-and-abstractbaseuser-in-django  class User(AbstractUser):      is_medical = models.BooleanField(default=False)      is_physiotherapist = models.BooleanField(default=False)      is_patient = models.BooleanField(default=False)      slug = models.SlugField(max_length=100, blank=True)      photo = models.ImageField(upload_to='avatars', null = True, blank = True)          # We get the profiles user according with their type      def get_medical_profile(self):          medical_profile = None          if hasattr(self, 'medicalprofile'):              medical_profile=self.medicalprofile          return medical_profile        def get_patient_profile(self):          patient_profile = None          if hasattr(self, 'patientprofile'):              patient_profile = self.patientprofile          return patient_profile        def get_physiotherapist_profile(self):          physiotherapist_profile = None          if hasattr(self, 'physiotherapistprofile'):              physiotherapist_profile = self.physiotherapistprofile          return physiotherapist_profile        # We redefine the attributes (create db_table attribute) in class Meta to say to Django      # that users will save in the same table that the Django default user model      # https://github.com/django/django/blob/master/django/contrib/auth/models.py#L343      class Meta:            db_table = 'auth_user'    class MedicalProfile(models.Model):      user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)      #active = models.BooleanField(default=True)      name = models.CharField(max_length=64)      class PatientProfile(models.Model):      user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)      #active = models.BooleanField(default=True)      name = models.CharField(max_length=64)      class PhysiotherapistProfile(models.Model):      user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)      #active = models.BooleanField(default=True)      name = models.CharField(max_length=64)      """  So we're defined a signal for the User model, that is triggered every time a User instance is saved    The arguments used in the create_profile_for_new_user  are:     sender: the User model class     created: a boolean indicating if a new User has been created     instance: the User instance being saved  """  @receiver(post_save, sender=settings.AUTH_USER_MODEL)  #def create_profile_for_new_user(sender, instance, created, **kwargs):  def create_profile_for_new_user(sender, instance, created, **kwargs):      user = instance      # ----------------- Begin debug----------------------      import ipdb      #ipdb.set_trace()      #------------------------      if created:          #ipdb.set_trace()          if user.is_medical:              ipdb.set_trace()              profile=MedicalProfile(user=instance)              profile.save()    """  This signal checks if a new instance of the User model has been created,  and if true, it creates a Profile instance with using the new user instance.  """


My Question

I want to focus my question in relation about of the post_save signal operation, this mean in the create_profile_for_new_user() method:


@receiver(post_save, sender=settings.AUTH_USER_MODEL)  def create_profile_for_new_user(sender, instance, created, **kwargs):      user = instance      # ----------------- Begin debug----------------------      import ipdb      #------------------------      if created:          if user.is_medical:              ipdb.set_trace()              profile=MedicalProfile(user=instance)              profile.save()


I want, each that an user is created, automatically (by post_save signal action) be created their profile (MedicalProfile, PatientProfile, PhysiotherapistProfile) according to if their field checked (is_medical, is_patient, is_physiotherapist) at the User class (same black image presented above)

The inconvenient that I have is with my signal, and it's the following:

  • When I create an user via django admin, indicating that this user is medical (have the is_medical field/attribute checked in the user admin form) in my MedicalProfile model, their profile instance not is saved or don't created

I have been checking the situation through ipdb basic debug functions and I think so that when I create the user the compiler or the steps don't arrive to the section when I check if my user is medical (if user.is_medical code line) such as follow:


1. I've placed a debug point initially of this way:


In the code section in where the user instance that has been created is sent


enter image description here



  1. 2. I create a user via django admin

I go to my Django admin and I create a new user and when press click in "Save" (first moment to user create): 


enter image description here



3. When I press "Save" button, the debug point enter to action


Then, I check the value of the variables that accord to my function which I am applying the signal are defined until the moment and they are inside the debug process. They are:

  • sendercreatedinstance (this mean, the parameters of the function)
  • user, that is the same instance variable

enter image description here


The above,denote that the parameters are arriving. All is O.K for the moment.



  1. 4. Moving the debug

  2. Then, I perform the debug a few more below in the code (red square in the following figure) and I analyze the following:

enter image description here


It's true the sender, instance and created parameters are arriving and when check for the is_medical attribute (boolean) which depend that the profil

...

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/e1532316-1770-480e-a870-624de2008283%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment