Django: How change the password of another user - django

I'm constructing site by Django.
I'm setting some authentications in this site, like Site Manager, Group Manager and Normal User.
When System Manager or Group Manager logged in, they could change the password of Normal Users as a part of system management.
In django, PasswordChangeForm or SetPasswordForm provide some user password change form. I think these forms are for changing password of users themselves.
Yes, I need that too. But I also need the form of changing the password of another users like django admin site.
How can I construct the form ?
I read the code of django's admin site.
I found AdminPasswordChangeForm, can I use this class ?
forms.py
class MyAdminPasswordChangeForm(AdminPasswordChangeForm):
def __init__(self, user, *args, **kwargs):
self.user = user
super().__init__(user, *args, **kwargs)
for field in self.fields.values():
field.widget.attrs['class'] = 'form-control'
views.py
class PasswordChange(PasswordChangeView):
form_class = MyAdminPasswordChangeForm
success_url = reverse_lazy('password_change_done')
template_name = 'accounts/password_change/password_admin_change.html'
def get(self, request, *args, **kwargs):
if 'user_id' in self.request.session:
user = User.objects.get(id=self.request.session['user_id'])
form_class = self.get_form_class()
form = form_class(user=user)
return self.render_to_response(self.get_context_data())
def get_form_class(self):
return self.form_class

you can use set_password() for change user passwords
first you should select user with such code
user=User.objects.get(username=username)
then you can set password
user.set_password(password)
user.save()

Related

Django (How to prevent users from directly accessing URLs in main_app/urls.py if the User is logged out and user.is_authenticated = FALSE

Django
How to prevent users from directly accessing URLS in main_app/urls.py if the user is logged out and user.is_authenticated = FALSE
Please note that I used Class Based Views in views.py. The condition if request.user.is_authenticated(): is not working. See below:
class EmployeeCreate(CreateView):
model = Employee
fields = ['first_name', 'last_name', 'role']
def post(self, request, *args, **kwargs):
if request.user.is_authenticated():
if "cancel" in request.POST:
return HttpResponseRedirect(reverse('main_app:index'))
elif "another" in request.POST:
return HttpResponseRedirect(reverse('main_app:employee-add'))
else:
return super(EmployeeCreate, self).post(request, *args, **kwargs)
Class LoginRequiredMixin solved the problem https://docs.djangoproject.com/en/2.0/topics/auth/default/#the-loginrequired-mixin

How to redirect the user back to the requested page after logging user in django?

I have been trying to develop a small app where some views require the user to be logged in. I am using method decorators to redirect the user to the login page. But after the user logs in he/she is redirected to the url defined in the success_url in my loginView. I want the user to be redirected to the page which the user was actually requesting.
Here is My LoginView
class LoginView(FormView):
template_name = 'draint_user/home.html'
form_class = LoginForm
# after login redirect users to the homepage again
success_url = '/artwork/upload'
def form_valid(self, form):
login(self.request, form.user_cache)
return HttpResponseRedirect(self.get_success_url())
And here is the View that requires login
class LoginRequiredMixin(View):
#method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
class ArtworkUpload(LoginRequiredMixin, FormView):
template_name = 'artwork/artwork_upload.html'
form_class = ArtForm
success_url = 'list'
def form_valid(self, form):
form.instance.draint_user = self.request.user
print form.instance.draint_user
artwork = form.save()
result = super(ArtworkUpload, self).form_valid(form)
return result
If the user is trying to view the ArtWorkUpload without logging in he is redirected to The LoginView. And after logging in I want him to be redirected to the ArtWorkUpload again.. Please suggest me some solutions .. Thanks in advance
2 ways are:
inspect HTTP_REFERER header
provide a next param with your post request

Access current user id on django model

I am overriding the save method on django model like this
def save(self, *args, **kwargs):
I want to get the current logged in user id on the save method. I can get the currently logged in user id?
Add in settings.py at MIDDLEWARE this line:
'crum.CurrentRequestUserMiddleware',
Then in models.py:
class MyModel(models.Model):
def save(self, *args, **kwargs):
userid = crum.get_current_user()
self.userid = userid.id
super(PlantSpecies, self).save(*args, **kwargs)
userid = models.CharField(max_length=45, blank=True, default=crum.get_current_user())
date = models.DateTimeField(auto_now_add=True)
Then in your forms template you can make the "userid" field hidden. If you look into your database you see that the current userid and date are automatically saed after submitting the form.
Instead of using the Model save method, you can use the save_model of Django ModelAdmin.
from django.contrib import admin
class ArticleAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.user = request.user
super().save_model(request, obj, form, change)
Please follow the link for details
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.save_model

How to save user in Django?

I can't find the answer to this problem which I guessed was very easy for Django.
I simply want to define an author field in a model, like this:
class Article(models.Model):
author = models.ForeignKey(User)
It seems there is no easy way like author = models.ForeignKey(User, default=current_user) so what is the easiest way to store the currently logged in user in the database? (if not logged in, a pre-defined default user called "anonymous" can be used)
Thanks for any help!
Currently logged user is available in the view as the request.user attribute:
def create_article(request):
...
if request.user.is_active():
article.author = request.user
article.save()
...
Alternatively, you can pass request.user to your form class and override the save:
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
def __init__(self, *args, **kwargs):
# Allows you to pass the user in from the request, or just set the property
if not hasattr(self, 'user'):
self.user = kwargs.pop('user')
super(ArticleForm, self).__init__(*args, **kwargs)
def save(self, commit=True)
article = super(ArticleForm, self).save(commit=False)
article.user = self.user
if commit:
article.save()
return article
Slightly more code, but it's encapsulated in the form class and not in the view, so you can use it in more than one place.
Example usage:
# in a view
#login_required
def your_view(request):
form = ArticleForm(request.POST or None, user=request.user)
. . .
# in Django admin
class ArticleAdmin(admin.ModelAdmin):
form = ArticleForm
def get_form(self, request, obj=None, **kwargs):
form = super(ArticleAdmin, self).get_form(request, obj, **kwargs)
form.user = request.user
return form
In either use case, you can be assured you have an authenticated user.

Extending user admin form in django

I'm trying to change user admin in Django. In my project the email address, first name and last name is required. I changed my user admin as following :
class UserForm(forms.ModelForm):
class Meta:
model = User
def __init__(self, *args, **kwargs):
super(UserForm, self).__init__(*args, **kwargs)
self.fields['email'].required = True
self.fields['first_name'].required = True
self.fields['last_name'].required = True
class UserAdmin(admin.ModelAdmin):
form = UserForm
list_display = ('first_name','last_name','email','is_active')
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
The problem is whenever I save a user with a password, it's displayed as without hashing. I guess the problem is, I need to hash the password field with my new form. But the old form does it, so is there a way that I can extend the oldform ?
You can subclass the existing UserChangeForm in django.contrib.auth.forms, and customise its behaviour, rather than subclassing forms.ModelForm.
from django.contrib.auth.forms import UserChangeForm
class MyUserChangeForm(UserChangeForm):
def __init__(self, *args, **kwargs):
super(MyUserChangeForm, self).__init__(*args, **kwargs)
self.fields['email'].required = True
self.fields['first_name'].required = True
self.fields['last_name'].required = True
class UserAdmin(admin.ModelAdmin):
form = MyUserChangeForm
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
The above will use the default behaviour for the user password, which is to display the password hash, and link to the password change form. If you want to modify that, I would look at SetPasswordForm, to see how the password is set in the Django admin.