Using post_save to assign a group on registration

I am new to Django and Python. I am attempting to auto assign a user to a group based on a choice made for a field when a user registers. I am attempting to use post_save.

However before I tackle trying to save the user to the group, I need to figure out how to get the Group id where business_location_state id is equal to Group forum_id.

Here is my models.py that includes the post_save attempt at the bottom.

from django.contrib.auth.models import AbstractUser
from django.db import models
from machina.core.db.models import get_model
from django.db.models import Q
from django.contrib.auth.models import Group
# signals imports
from django.dispatch import receiver
from django.db.models.signals import (
    post_save
)

Forum = get_model("forum", "Forum")

class CustomUser(AbstractUser):
    age = models.PositiveIntegerField(null=True, blank=True)
    business_location_state = models.ForeignKey(Forum, null=True,  on_delete=models.SET_NULL, limit_choices_to={"lft":1})
    business_location_county = models.ForeignKey(Forum, null=True, on_delete=models.SET_NULL, related_name='county', limit_choices_to=(~Q(lft__in = (1,2))))


Group.add_to_class('forum_id', models.PositiveIntegerField(null=True, blank=True))

def user_addgroup_handler(sender, instance, created, *args, **kwargs):
    g = Group.objects.get(id, limit_choices_to=(Q(forum_id__in = CustomUser.business_location_county)))
    print (g)


post_save.connect(user_addgroup_handler, sender=CustomUser)

So far I am not able to get this to work.

I wouldn’t use a signal here. This appears to be something that is only done once when the user is created and not something done every time a change is saved to the User object (such as changing their password).
I would add that functionality to the view where the user is being registered.

@KenWhitesell
What would you do in case Django Admin is used ?
For example, I have a case that when new Candidate is saved, I have to create new User and send him/her password reset link so he/she can set the password.
I’m using Django Admin to manage Candidate.

class CandidateAdmin(admin.ModelAdmin):
    fields = ('email', 'name', 'address')

There are numerous “hooks” available in the ModelAdmin class to alter / augment the default behavior. In this case, see response_add.

I had to do something similar… I ended doing something like this (like Ken suggest):

In my case I have a custom button in the admin change view, If I click the button _Validate I will set the field ‘inspector_validation’ on the instance to True. Note that you have to save the object. You can obviously create an other object.

I also display a notification in the admin when done.

Note also the the response_add() method is called after the instance has been saved !

...
@admin.register(Ncf)
class NCFAdmin(admin.ModelAdmin):
    ...
    def response_add(self, request, obj, post_url_continue=None):
        if '_validate' in request.POST:
            obj.inspector_validation = True
            obj.save()
            self.message_user(request, "The NCF has been validated")
        return super(NCFAdmin, self).response_add(request, obj, post_url_continue)
    ...

hope this help…

1 Like