Andrew Stevens
Andrew Stevens

Reputation: 41

How to set the value of a field when creating a user, based on the value of the current user

I'm creating a form where users can register additional users, and I need to automatically pass the foreign key (organization) of the current user to the new user being created.

I'm relatively new to Django, but I believe the issue is with the following line in the forms:

"user.organization = self.instance.organization"

Model

class Organization(models.Model):
    name = models.CharField(max_length=255)
    address = models.CharField(max_length=255)
    city = models.CharField(max_length=255)
    state = models.CharField(max_length=255)
    zip = models.CharField(max_length=255)

class User(AbstractUser):
    username = None
    email = models.EmailField(_('email address'), unique=True)
    organization = models.ForeignKey(Organization, on_delete=models.CASCADE, blank=True, null=True)
    client = models.ForeignKey(Client, on_delete=models.CASCADE, blank=True, null=True)
    user_type = models.CharField(max_length=255, choices=(('org_admin', 'Admin'),('org_user','User'),('client_admin','Client Admin'),('client_user','Client User')))

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = UserManager()

View

def register(request):
    if request.method == 'POST':
        form = UserOrgCreationForm(request.POST)
        if form.is_valid():
            form.save()
            email = form.cleaned_data.get('email')
            messages.success(request, f'User has been created')
            # return redirect('login')
    else:
        form = UserOrgCreationForm()
    return render(request, 'users/register.html', {'form': form})

Form

class UserOrgCreationForm(UserCreationForm):

    password1 = None
    password2 = None

    class Meta:
        model = User
        fields = ('email', 'first_name', 'last_name', 'user_type')

    def save(self, commit=True):
        user = super(UserCreationForm, self).save(commit=False)
        user.set_unusable_password()
        user.organization = self.instance.organization
        if commit:
            user.save()
        return user

I need the new user to inherit the organization of the current user.

Upvotes: 1

Views: 33

Answers (3)

Rohan
Rohan

Reputation: 53366

Since your form is not based on existing instance (not passed when creating form instance), you cannot refer to that while saving.

You can do what you want in view as below

def register(request):
    if request.method == 'POST':
        form = UserOrgCreationForm(request.POST)
        if form.is_valid():
            new_user = form.save(commit=False)
            new_user.organization = request.user.organization
            new_user.save()
            email = form.cleaned_data.get('email')
            messages.success(request, f'User has been created')
            # return redirect('login')
    else:
        form = UserOrgCreationForm()
    return render(request, 'users/register.html', {'form': form})

Upvotes: 1

Ben Boyer
Ben Boyer

Reputation: 1234

You need to access the request.user.organisation form the form save.

class UserOrgCreationForm(UserCreationForm):

    password1 = None
    password2 = None

    class Meta:
        model = User
        fields = ('email', 'first_name', 'last_name', 'user_type')

    def save(self, commit=True):
        user = super(UserCreationForm, self).save(commit=False)
        user.set_unusable_password()
        user.organization = current_user.organization
        if commit:
            user.save()
        return user

    def __init__(self,*args,**kwargs):
        self.current_user = kwargs.pop("current_user", None)
        super(UserOrgCreationForm,self).__init__(*args,**kwargs)

And from the view:

def register(request):
    form = UserOrgCreationForm(request.POST or None, current_user=request.user)
    if form.is_valid():
        form.save()
        email = form.cleaned_data.get('email')
        messages.success(request, f'User has been created')
        # return redirect('login')

    return render(request, 'users/register.html', {'form': form})

Upvotes: 0

Scott Woodall
Scott Woodall

Reputation: 10676

You can leverage commit=False parameter. This won't save the form to the database until .save() is called a second time.

def register(request):
    if request.method == 'POST':
        form = UserOrgCreationForm(request.POST)
        if form.is_valid():
            obj = form.save(commit=False)
            obj.organization = request.user.organization
            obj.save()
            email = form.cleaned_data.get('email')
            messages.success(request, f'User has been created')
            # return redirect('login')
    else:
        form = UserOrgCreationForm()
    return render(request, 'users/register.html', {'form': form})

Upvotes: 0

Related Questions