In my Django project, there are several types of users. User types are lead
, manager
, analyst
. The Leads should change every user’s is_active
attribute. I created a form and view for that. I have a users page and every user is listing here with a for
loop.
What I want is lead
can block a user with is_active = False
method. But my form is does not work because I think I cannot reach the user. How can I solve it?
views.py
@user_passes_test(is_lead)
def users(request):
if request.method == 'POST': form = makeInactive(request.POST, user=request.user) if form.is_valid(): data = form.cleaned_data profile = data.get("profile") profile.isUserActive = data.get("isUserActive") profile.save() # get User user = get_user_model().objects.get(id=profile.user_id) user.is_active = data.get("isUserActive") user.save() else: form = makeInactive(user=request.user) context = { 'form': form } return render(request, 'user_list.html', context)
forms.py
class makeInactive(forms.ModelForm): isUserActive = forms.BooleanField(label='', widget=forms.CheckboxInput( attrs={'onclick': 'this.form.submit();'}), required=False) profile = forms.ModelChoiceField( queryset=UserProfile.objects.none(), empty_label="Select an user" ) class Meta: model = UserProfile fields = ('isUserActive',) def __init__(self, user, *args, **kwargs): super(makeInactive, self).__init__(*args, **kwargs) userP = UserProfile.objects.get_or_create(username=user.username) self.fields['profile'].queryset = UserProfile.objects.filter( company=userP[0].company ).order_by('-first_name')
models.py
class UserProfile(AbstractUser): company = models.ForeignKey(CompanyProfile, on_delete=models.CASCADE, null=True, unique=False) user_id = models.UUIDField(default=uuid.uuid4(), editable=False, unique=True) username = models.CharField(max_length=500, unique=True) first_name = models.CharField(max_length=200) last_name = models.CharField(max_length=200) password = models.CharField(max_length=250) email = models.EmailField(max_length=254) rank = models.ForeignKey(Rank, on_delete=models.CASCADE, null=True, unique=False) image = models.ImageField(upload_to='profile_image', blank=True, null= True, default='profile.png') isUserActive = models.BooleanField(default=True)
traceback
Environment: Request Method: POST Request URL: http://127.0.0.1:8000/users Django Version: 3.1.4 Python Version: 3.8.7 Installed Applications: ['django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'register', 'customer', 'financial_analysis', 'ocr', 'core', 'approvals', 'crispy_forms', 'ckeditor', 'rest_framework', 'requests', 'ckeditor_uploader', 'django_filters'] Installed Middleware: ['django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware'] Traceback (most recent call last): File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangocorehandlersexception.py", line 47, in inner response = get_response(request) File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangocorehandlersbase.py", line 179, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangocontribauthdecorators.py", line 21, in _wrapped_view return view_func(request, *args, **kwargs) File "C:UsersUSEROneDriveDocumentsGitHubotcregisterviews.py", line 101, in users form = makeInactive(request.POST, user=request.user) Exception Type: TypeError at /users Exception Value: __init__() got multiple values for argument 'user'
Advertisement
Answer
You can use forms.ModelChoiceField
(Dango Docs) in the MakeInactive
form. Also instead forms.ModelForm
use forms.Form
.
Then the UserProfile
with rank lead can select a UserProfile
with rank manager or analyst and set it inactive.
You can add the current user to MakeInactive
form and filter the UserProfile
in the __init__
method.
You cat try to use the below code:
forms.py:
class MakeInactive(forms.Form): isUserActive = forms.BooleanField( label='', widget=forms.CheckboxInput( attrs={'onclick': 'this.form.submit();'}) ) profile = forms.ModelChoiceField( queryset=UserProfile.objects.none(), empty_label="Select an user") def __init__(self, *args, **kwargs): user = kwargs.pop('user', None) super().__init__(*args, **kwargs) if user: userP = UserProfile.objects.get_or_create(username=user.username) self.fields['profile'].queryset = UserProfile.objects.filter( rank_id__in=["manager", "analyst"], company=userP[0].company ).order_by('-first_name')
views.py:
from django.contrib.auth import get_user_model @user_passes_test(is_lead) def users(request): if request.method == 'POST': form = makeInactive(request.POST, user=request.user) if form.is_valid(): data = form.cleaned_data profile = data.get("profile") profile.isUserActive = data.get("isUserActive") profile.save() # get User user = get_user_model().objects.get(id=profile.user_id) user.is_active = data.get("isUserActive") user.save() else: form = makeInactive(user=request.user) context = { 'form': form } return render(request, 'user_list.html', context)