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): | ... | ... |