Commit 22b917518e2e1105fb74278490055ecc978528a4
1 parent
fbf424a9
Exists in
master
and in
39 other branches
Fixed admin for User model
(flake8 checks as well)
Showing
2 changed files
with
97 additions
and
103 deletions
Show diff stats
colab/accounts/admin.py
| 1 | 1 | |
| 2 | -from django import forms | |
| 3 | 2 | from django.contrib import admin |
| 4 | 3 | from django.contrib.auth import get_user_model |
| 5 | 4 | from django.contrib.auth.admin import UserAdmin |
| 6 | 5 | from django.utils.translation import ugettext_lazy as _ |
| 7 | 6 | |
| 8 | -from .forms import UserCreationForm | |
| 7 | +from .forms import UserCreationForm, UserChangeForm | |
| 9 | 8 | |
| 10 | 9 | User = get_user_model() |
| 11 | 10 | |
| 12 | 11 | |
| 13 | -class CustomUserCreationForm(UserCreationForm): | |
| 14 | - class Meta: | |
| 15 | - model = User | |
| 16 | - fields = ("username", "email") | |
| 17 | - | |
| 18 | - #def __init__(self, *args, **kwargs): | |
| 19 | - # super(CustomUserCreationForm, self).__init__(*args, **kwargs) | |
| 20 | - # self.fields['email'].required = True | |
| 21 | - | |
| 22 | - | |
| 23 | -class UserChangeForm(forms.ModelForm): | |
| 24 | - class Meta: | |
| 25 | - model = User | |
| 26 | - fields = ('username', 'first_name', 'last_name', 'email', 'is_active', | |
| 27 | - 'is_staff', 'is_superuser', 'groups', 'last_login', | |
| 28 | - 'date_joined', 'twitter', 'facebook', 'google_talk', | |
| 29 | - 'webpage') | |
| 30 | - | |
| 31 | - def __init__(self, *args, **kwargs): | |
| 32 | - super(UserChangeForm, self).__init__(*args, **kwargs) | |
| 33 | - self.fields['email'].required = True | |
| 34 | - | |
| 35 | - | |
| 36 | - | |
| 37 | -class MyUserAdmin(UserAdmin): | |
| 12 | +class CustomUserAdmin(UserAdmin): | |
| 38 | 13 | form = UserChangeForm |
| 39 | - add_form = CustomUserCreationForm | |
| 14 | + add_form = UserCreationForm | |
| 40 | 15 | |
| 41 | 16 | fieldsets = ( |
| 42 | 17 | (None, {'fields': ('username', 'email', 'password')}), |
| 43 | - (_('Personal info'), {'fields': ('first_name', 'last_name', 'twitter', | |
| 44 | - 'facebook', 'google_talk', 'webpage', | |
| 45 | - )}), | |
| 46 | - (_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser', | |
| 18 | + (_('Personal info'), {'fields': ('first_name', | |
| 19 | + 'last_name', | |
| 20 | + 'twitter', | |
| 21 | + 'facebook', | |
| 22 | + 'google_talk', | |
| 23 | + 'webpage')}), | |
| 24 | + (_('Permissions'), {'fields': ('is_active', | |
| 25 | + 'is_staff', | |
| 26 | + 'is_superuser', | |
| 47 | 27 | 'groups')}), |
| 48 | 28 | (_('Important dates'), {'fields': ('last_login', 'date_joined')}) |
| 49 | 29 | ) |
| ... | ... | @@ -56,4 +36,4 @@ class MyUserAdmin(UserAdmin): |
| 56 | 36 | ) |
| 57 | 37 | |
| 58 | 38 | |
| 59 | -admin.site.register(User, MyUserAdmin) | |
| 39 | +admin.site.register(User, CustomUserAdmin) | ... | ... |
colab/accounts/forms.py
| 1 | 1 | # -*- coding: utf-8 -*- |
| 2 | 2 | |
| 3 | +from collections import OrderedDict | |
| 4 | + | |
| 3 | 5 | from django import forms |
| 4 | -from django.contrib.auth import get_user_model | |
| 5 | -from django.contrib.auth.forms import OrderedDict, ReadOnlyPasswordHashField, \ | |
| 6 | - default_token_generator | |
| 6 | +from django.contrib.auth import authenticate, get_user_model | |
| 7 | +from django.contrib.auth.forms import ReadOnlyPasswordHashField | |
| 8 | +from django.contrib.auth.tokens import default_token_generator | |
| 9 | +from django.contrib.sites.shortcuts import get_current_site | |
| 10 | +from django.template import loader | |
| 11 | +from django.utils.encoding import force_bytes | |
| 12 | +from django.utils.http import urlsafe_base64_encode | |
| 13 | +from django.utils.text import capfirst | |
| 7 | 14 | from django.utils.translation import ugettext_lazy as _ |
| 8 | 15 | |
| 9 | 16 | from conversejs.models import XMPPAccount |
| 10 | 17 | |
| 11 | -from ..super_archives.models import MailingList | |
| 12 | 18 | from .utils.validators import validate_social_account |
| 13 | 19 | from .utils import mailman |
| 14 | 20 | |
| ... | ... | @@ -32,7 +38,7 @@ class UserForm(forms.ModelForm): |
| 32 | 38 | username = forms.CharField( |
| 33 | 39 | |
| 34 | 40 | # Forces username to be lowercase always |
| 35 | - widget=forms.TextInput(attrs={'style' : 'text-transform: lowercase;'}), | |
| 41 | + widget=forms.TextInput(attrs={'style': 'text-transform: lowercase;'}), | |
| 36 | 42 | ) |
| 37 | 43 | required = ('first_name', 'last_name', 'username') |
| 38 | 44 | |
| ... | ... | @@ -50,48 +56,6 @@ class UserForm(forms.ModelForm): |
| 50 | 56 | field.required = True |
| 51 | 57 | |
| 52 | 58 | |
| 53 | -class UserCreationForm(UserForm): | |
| 54 | - | |
| 55 | - class Meta: | |
| 56 | - model = User | |
| 57 | - fields = ('first_name', 'last_name', 'username') | |
| 58 | - | |
| 59 | - def clean_username(self): | |
| 60 | - username = self.cleaned_data['username'] | |
| 61 | - username = username.strip() | |
| 62 | - if not username: | |
| 63 | - raise forms.ValidationError(_('This field cannot be blank.')) | |
| 64 | - return username | |
| 65 | - | |
| 66 | - | |
| 67 | -class UserCreationFormNoBrowserId(UserCreationForm): | |
| 68 | - | |
| 69 | - password1 = forms.CharField(label=_("Password"), widget=forms.PasswordInput) | |
| 70 | - password2 = forms.CharField(label=_("Confirm Password "), widget=forms.PasswordInput) | |
| 71 | - email = forms.EmailField(label=_("Email address"), required=True) | |
| 72 | - | |
| 73 | - class Meta: | |
| 74 | - model = User | |
| 75 | - fields = ('first_name', 'last_name','email', 'username') | |
| 76 | - | |
| 77 | - def clean_password2(self): | |
| 78 | - password1 = self.cleaned_data.get('password1') | |
| 79 | - password2 = self.cleaned_data.get('password2') | |
| 80 | - | |
| 81 | - if password1 and password2 and password1 != password2: | |
| 82 | - raise forms.ValidationError(_("The two password fields didn't match.")) | |
| 83 | - return password2 | |
| 84 | - | |
| 85 | - def save(self, commit=True): | |
| 86 | - """ | |
| 87 | - Saves the new password. | |
| 88 | - """ | |
| 89 | - self.instance.set_password(self.cleaned_data["password1"]) | |
| 90 | - if commit: | |
| 91 | - self.instance.save() | |
| 92 | - return self.instance | |
| 93 | - | |
| 94 | - | |
| 95 | 59 | class UserUpdateForm(UserForm): |
| 96 | 60 | bio = forms.CharField( |
| 97 | 61 | widget=forms.Textarea(attrs={'rows': '6', 'maxlength': '200'}), |
| ... | ... | @@ -102,10 +66,9 @@ class UserUpdateForm(UserForm): |
| 102 | 66 | ) |
| 103 | 67 | |
| 104 | 68 | def __init__(self, *args, **kwargs): |
| 105 | - super (UserUpdateForm, self).__init__(*args, **kwargs) | |
| 69 | + super(UserUpdateForm, self).__init__(*args, **kwargs) | |
| 106 | 70 | self.fields.pop('username') |
| 107 | 71 | |
| 108 | - | |
| 109 | 72 | class Meta: |
| 110 | 73 | model = User |
| 111 | 74 | fields = ('first_name', 'last_name', |
| ... | ... | @@ -113,7 +76,8 @@ class UserUpdateForm(UserForm): |
| 113 | 76 | 'google_talk', 'github', 'webpage', 'bio') |
| 114 | 77 | |
| 115 | 78 | twitter = SocialAccountField(url='https://twitter.com/', required=False) |
| 116 | - facebook = SocialAccountField(url='https://graph.facebook.com/', required=False) | |
| 79 | + facebook = SocialAccountField(url='https://graph.facebook.com/', | |
| 80 | + required=False) | |
| 117 | 81 | |
| 118 | 82 | |
| 119 | 83 | class ListsForm(forms.Form): |
| ... | ... | @@ -129,10 +93,11 @@ class ListsForm(forms.Form): |
| 129 | 93 | |
| 130 | 94 | class ChangeXMPPPasswordForm(forms.ModelForm): |
| 131 | 95 | password1 = forms.CharField(label=_("Password"), |
| 132 | - widget=forms.PasswordInput) | |
| 96 | + widget=forms.PasswordInput) | |
| 133 | 97 | password2 = forms.CharField(label=_("Password confirmation"), |
| 134 | - widget=forms.PasswordInput, | |
| 135 | - help_text=_("Enter the same password as above, for verification.")) | |
| 98 | + widget=forms.PasswordInput, | |
| 99 | + help_text=_(("Enter the same password as above" | |
| 100 | + ", for verification."))) | |
| 136 | 101 | |
| 137 | 102 | class Meta: |
| 138 | 103 | model = XMPPAccount |
| ... | ... | @@ -161,6 +126,7 @@ class ChangeXMPPPasswordForm(forms.ModelForm): |
| 161 | 126 | self.instance.save() |
| 162 | 127 | return self.instance |
| 163 | 128 | |
| 129 | + | |
| 164 | 130 | class UserCreationForm(forms.ModelForm): |
| 165 | 131 | """ |
| 166 | 132 | A form that creates a user, with no privileges, from the given username and |
| ... | ... | @@ -171,17 +137,21 @@ class UserCreationForm(forms.ModelForm): |
| 171 | 137 | 'password_mismatch': _("The two password fields didn't match."), |
| 172 | 138 | } |
| 173 | 139 | username = forms.RegexField(label=_("Username"), max_length=30, |
| 174 | - regex=r'^[\w.@+-]+$', | |
| 175 | - help_text=_("Required. 30 characters or fewer. Letters, digits and " | |
| 176 | - "@/./+/-/_ only."), | |
| 177 | - error_messages={ | |
| 178 | - 'invalid': _("This value may contain only letters, numbers and " | |
| 179 | - "@/./+/-/_ characters.")}) | |
| 140 | + regex=r'^[\w.@+-]+$', | |
| 141 | + help_text=_(("Required. 30 characters or fewer" | |
| 142 | + ". Letters, digits and " | |
| 143 | + "@/./+/-/_ only.")), | |
| 144 | + error_messages={ | |
| 145 | + 'invalid': _(("This value may contain only" | |
| 146 | + " letters, numbers and " | |
| 147 | + "@/./+/-/_ characters."))}) | |
| 180 | 148 | password1 = forms.CharField(label=_("Password"), |
| 181 | - widget=forms.PasswordInput) | |
| 149 | + widget=forms.PasswordInput) | |
| 182 | 150 | password2 = forms.CharField(label=_("Password confirmation"), |
| 183 | - widget=forms.PasswordInput, | |
| 184 | - help_text=_("Enter the same password as above, for verification.")) | |
| 151 | + widget=forms.PasswordInput, | |
| 152 | + help_text=_(("Enter the same password as above" | |
| 153 | + ", for verification."))) | |
| 154 | + email = forms.EmailField(required=True) | |
| 185 | 155 | |
| 186 | 156 | class Meta: |
| 187 | 157 | model = User |
| ... | ... | @@ -190,7 +160,7 @@ class UserCreationForm(forms.ModelForm): |
| 190 | 160 | def clean_username(self): |
| 191 | 161 | # Since User.username is unique, this check is redundant, |
| 192 | 162 | # but it sets a nicer error message than the ORM. See #13147. |
| 193 | - username = self.cleaned_data["username"] | |
| 163 | + username = self.cleaned_data["username"].strip() | |
| 194 | 164 | try: |
| 195 | 165 | User._default_manager.get(username=username) |
| 196 | 166 | except User.DoesNotExist: |
| ... | ... | @@ -227,9 +197,15 @@ class UserChangeForm(forms.ModelForm): |
| 227 | 197 | 'invalid': _("This value may contain only letters, numbers and " |
| 228 | 198 | "@/./+/-/_ characters.")}) |
| 229 | 199 | password = ReadOnlyPasswordHashField(label=_("Password"), |
| 230 | - help_text=_("Raw passwords are not stored, so there is no way to see " | |
| 231 | - "this user's password, but you can change the password " | |
| 232 | - "using <a href=\"password/\">this form</a>.")) | |
| 200 | + help_text=_("Raw passwords are not" | |
| 201 | + " stored, so there is no" | |
| 202 | + " way to see " | |
| 203 | + "this user's password, " | |
| 204 | + "but you can change the " | |
| 205 | + "password " | |
| 206 | + "using <a " | |
| 207 | + "href=\"password/\">this" | |
| 208 | + " form</a>.")) | |
| 233 | 209 | |
| 234 | 210 | class Meta: |
| 235 | 211 | model = User |
| ... | ... | @@ -241,6 +217,9 @@ class UserChangeForm(forms.ModelForm): |
| 241 | 217 | if f is not None: |
| 242 | 218 | f.queryset = f.queryset.select_related('content_type') |
| 243 | 219 | |
| 220 | + # Set email as required field | |
| 221 | + self.fields['email'].required = True | |
| 222 | + | |
| 244 | 223 | def clean_password(self): |
| 245 | 224 | # Regardless of what the user provides, return the initial value. |
| 246 | 225 | # This is done here, rather than on the field, because the |
| ... | ... | @@ -248,6 +227,37 @@ class UserChangeForm(forms.ModelForm): |
| 248 | 227 | return self.initial["password"] |
| 249 | 228 | |
| 250 | 229 | |
| 230 | +class UserCreationFormNoBrowserId(UserCreationForm): | |
| 231 | + | |
| 232 | + password1 = forms.CharField(label=_("Password"), | |
| 233 | + widget=forms.PasswordInput) | |
| 234 | + password2 = forms.CharField(label=_("Confirm Password "), | |
| 235 | + widget=forms.PasswordInput) | |
| 236 | + email = forms.EmailField(label=_("Email address"), required=True) | |
| 237 | + | |
| 238 | + class Meta: | |
| 239 | + model = User | |
| 240 | + fields = ('first_name', 'last_name', 'email', 'username') | |
| 241 | + | |
| 242 | + def clean_password2(self): | |
| 243 | + password1 = self.cleaned_data.get('password1') | |
| 244 | + password2 = self.cleaned_data.get('password2') | |
| 245 | + | |
| 246 | + if password1 and password2 and password1 != password2: | |
| 247 | + raise forms.ValidationError( | |
| 248 | + _("The two password fields didn't match.")) | |
| 249 | + return password2 | |
| 250 | + | |
| 251 | + def save(self, commit=True): | |
| 252 | + """ | |
| 253 | + Saves the new password. | |
| 254 | + """ | |
| 255 | + self.instance.set_password(self.cleaned_data["password1"]) | |
| 256 | + if commit: | |
| 257 | + self.instance.save() | |
| 258 | + return self.instance | |
| 259 | + | |
| 260 | + | |
| 251 | 261 | class AuthenticationForm(forms.Form): |
| 252 | 262 | """ |
| 253 | 263 | Base class for authenticating users. Extend this to get a form that accepts |
| ... | ... | @@ -273,9 +283,11 @@ class AuthenticationForm(forms.Form): |
| 273 | 283 | |
| 274 | 284 | # Set the label for the "username" field. |
| 275 | 285 | UserModel = get_user_model() |
| 276 | - self.username_field = UserModel._meta.get_field(UserModel.USERNAME_FIELD) | |
| 286 | + self.username_field = UserModel._meta.get_field( | |
| 287 | + UserModel.USERNAME_FIELD) | |
| 277 | 288 | if self.fields['username'].label is None: |
| 278 | - self.fields['username'].label = capfirst(self.username_field.verbose_name) | |
| 289 | + self.fields['username'].label = capfirst( | |
| 290 | + self.username_field.verbose_name) | |
| 279 | 291 | |
| 280 | 292 | def clean(self): |
| 281 | 293 | username = self.cleaned_data.get('username') |
| ... | ... | @@ -362,10 +374,12 @@ class PasswordResetForm(forms.Form): |
| 362 | 374 | email = loader.render_to_string(email_template_name, c) |
| 363 | 375 | |
| 364 | 376 | if html_email_template_name: |
| 365 | - html_email = loader.render_to_string(html_email_template_name, c) | |
| 377 | + html_email = loader.render_to_string(html_email_template_name, | |
| 378 | + c) | |
| 366 | 379 | else: |
| 367 | 380 | html_email = None |
| 368 | - send_mail(subject, email, from_email, [user.email], html_message=html_email) | |
| 381 | + send_mail(subject, email, from_email, [user.email], | |
| 382 | + html_message=html_email) | |
| 369 | 383 | |
| 370 | 384 | |
| 371 | 385 | class SetPasswordForm(forms.Form): | ... | ... |