소스 검색

Add support for a truly custom User model

The new model must have an email field but Oscar will work without
anything else.
master
David Winterbottom 12 년 전
부모
커밋
d4e51bb6f9

+ 10
- 3
oscar/apps/customer/auth_backends.py 파일 보기

@@ -6,12 +6,19 @@ from oscar.core.compat import get_user_model
6 6
 
7 7
 User = get_user_model()
8 8
 
9
-if hasattr(User, 'REQUIRED_FIELDS') and 'email' not in User.REQUIRED_FIELDS:
10
-    raise ImproperlyConfigured("Emailbackend: Your User model must have an email"
11
-                               " field with blank=False")
9
+if hasattr(User, 'REQUIRED_FIELDS'):
10
+    if not (User.USERNAME_FIELD == 'email' or 'email' in User.REQUIRED_FIELDS):
11
+        raise ImproperlyConfigured(
12
+            "Emailbackend: Your User model must have an email"
13
+            " field with blank=False")
12 14
 
13 15
 
14 16
 class Emailbackend(ModelBackend):
17
+    """
18
+    Custom auth backend that users an email address
19
+
20
+    For this to work, the User model must have an 'email' field
21
+    """
15 22
 
16 23
     def authenticate(self, email=None, password=None, *args, **kwargs):
17 24
         if email is None:

+ 31
- 19
oscar/apps/customer/forms.py 파일 보기

@@ -240,15 +240,8 @@ Profile = get_profile_class()
240 240
 if Profile:
241 241
 
242 242
     class UserAndProfileForm(forms.ModelForm):
243
-        first_name = forms.CharField(
244
-            label=_('First name'), max_length=128, required=False)
245
-        last_name = forms.CharField(
246
-            label=_('Last name'), max_length=128, required=False)
247 243
         email = forms.EmailField(label=_('Email address'), required=True)
248 244
 
249
-        # Fields from user model
250
-        user_fields = ('first_name', 'last_name', 'email')
251
-
252 245
         def __init__(self, user, *args, **kwargs):
253 246
             self.user = user
254 247
             try:
@@ -260,17 +253,34 @@ if Profile:
260 253
 
261 254
             super(UserAndProfileForm, self).__init__(*args, **kwargs)
262 255
 
263
-            # Add user fields
264
-            self.fields['first_name'].initial = self.instance.user.first_name
265
-            self.fields['last_name'].initial = self.instance.user.last_name
256
+            # Get a list of profile fields to help with ordering later
257
+            profile_field_names = self.fields.keys()
258
+            del profile_field_names[profile_field_names.index('email')]
259
+
266 260
             self.fields['email'].initial = self.instance.user.email
267 261
 
268
-            # Ensure user fields are above profile
269
-            order = list(self.user_fields)
270
-            for field_name in self.fields.keys():
271
-                if field_name not in self.user_fields:
272
-                    order.append(field_name)
273
-            self.fields.keyOrder = order
262
+            # Add user fields (we look for core user fields first)
263
+            core_field_names = set([f.name for f in User._meta.fields])
264
+            user_field_names = ['email']
265
+            for field_name in ('first_name', 'last_name'):
266
+                if field_name in core_field_names:
267
+                    user_field_names.append(field_name)
268
+            user_field_names.extend(User._meta.additional_fields)
269
+
270
+            # Store user fields so we know what to save later
271
+            self.user_field_names = user_field_names
272
+
273
+            # Add additional user fields
274
+            additional_fields = forms.fields_for_model(
275
+                User, fields=user_field_names)
276
+            self.fields.update(additional_fields)
277
+
278
+            # Set initial values
279
+            for field_name in user_field_names:
280
+                self.fields[field_name].initial = getattr(user, field_name)
281
+
282
+            # Ensure order of fields is email, user fields then profile fields
283
+            self.fields.keyOrder = user_field_names + profile_field_names
274 284
 
275 285
         class Meta:
276 286
             model = Profile
@@ -290,10 +300,12 @@ if Profile:
290 300
 
291 301
         def save(self, *args, **kwargs):
292 302
             user = self.instance.user
293
-            user.first_name = self.cleaned_data['first_name']
294
-            user.last_name = self.cleaned_data['last_name']
295
-            user.email = self.cleaned_data['email']
303
+
304
+            # Save user also
305
+            for field_name in self.user_field_names:
306
+                setattr(user, field_name, self.cleaned_data[field_name])
296 307
             user.save()
308
+
297 309
             return super(ProfileForm, self).save(*args, **kwargs)
298 310
 
299 311
     ProfileForm = UserAndProfileForm

+ 6
- 5
oscar/apps/customer/views.py 파일 보기

@@ -38,6 +38,7 @@ CommunicationEventType = get_model('customer', 'CommunicationEventType')
38 38
 ProductAlert = get_model('customer', 'ProductAlert')
39 39
 User = get_user_model()
40 40
 
41
+
41 42
 class LogoutView(RedirectView):
42 43
     url = '/'
43 44
     permanent = False
@@ -123,6 +124,11 @@ class AccountSummaryView(TemplateView):
123 124
     def get_profile_fields(self, user):
124 125
         field_data = []
125 126
 
127
+        # Check for custom user model
128
+        for field_name in User._meta.additional_fields:
129
+            field_data.append(
130
+                self.get_model_field_data(user, field_name))
131
+
126 132
         # Check for profile class
127 133
         profile_class = get_profile_class()
128 134
         if profile_class:
@@ -137,11 +143,6 @@ class AccountSummaryView(TemplateView):
137 143
                 field_data.append(
138 144
                     self.get_model_field_data(profile, field_name))
139 145
 
140
-        # Check for custom user model
141
-        for field_name in User._meta.additional_fields:
142
-            field_data.append(
143
-                self.get_model_field_data(user, field_name))
144
-
145 146
         return field_data
146 147
 
147 148
     def get_model_field_data(self, model_class, field_name):

+ 6
- 8
oscar/templates/oscar/customer/profile.html 파일 보기

@@ -65,10 +65,6 @@
65 65
             </div>
66 66
             <table class="table table-striped table-bordered">
67 67
                 <tbody>
68
-                    <tr>
69
-                        <th>{% trans 'Name' %}</th>
70
-                        <td>{{ request.user.get_full_name|default:'-' }}</td>
71
-                    </tr>
72 68
                     <tr>
73 69
                         <th>{% trans 'Email address' %}</th>
74 70
                         <td>{{ user.email }}</td>
@@ -81,10 +77,12 @@
81 77
                         </tr>
82 78
                         {% endfor %}
83 79
                     {% endblock %}
84
-                    <tr>
85
-                        <th>{% trans 'Date registered' %}</th>
86
-                        <td>{{ user.date_joined }}</td>
87
-                    </tr>
80
+                    {% if user.date_joined %}
81
+                        <tr>
82
+                            <th>{% trans 'Date registered' %}</th>
83
+                            <td>{{ user.date_joined }}</td>
84
+                        </tr>
85
+                    {% endif %}
88 86
                 </tbody>
89 87
             </table>
90 88
 

+ 35
- 1
sites/sandbox/apps/user/models.py 파일 보기

@@ -1,4 +1,5 @@
1 1
 from django.db import models
2
+from django.utils import timezone
2 3
 
3 4
 from django.contrib.auth import models as auth_models
4 5
 
@@ -20,5 +21,38 @@ class Profile(models.Model):
20 21
 
21 22
 
22 23
 # A simple extension of the core User model
23
-class CustomUserModel(auth_models.AbstractUser):
24
+class ExtendedUserModel(auth_models.AbstractUser):
24 25
     twitter_username = models.CharField(max_length=255, unique=True)
26
+
27
+
28
+class CustomUserManager(auth_models.BaseUserManager):
29
+
30
+    def create_user(self, email, password=None):
31
+        now = timezone.now()
32
+        email = auth_models.BaseUserManager.normalize_email(email)
33
+        user = self.model(email=email, last_login=now)
34
+        user.set_password(password)
35
+        user.save(using=self._db)
36
+        return user
37
+
38
+    def create_superuser(self, email, password):
39
+        return self.create_user(email, password)
40
+
41
+
42
+# A user model which doesn't extend AbstractUser
43
+class CustomUserModel(auth_models.AbstractBaseUser):
44
+    name = models.CharField(max_length=255, blank=True)
45
+    email = models.EmailField(unique=True)
46
+    twitter_username = models.CharField(max_length=255, unique=True)
47
+
48
+    USERNAME_FIELD = 'email'
49
+
50
+    objects = CustomUserManager()
51
+
52
+    def __unicode__(self):
53
+        return self.email
54
+
55
+    def get_full_name(self):
56
+        return self.name
57
+
58
+    get_short_name = get_full_name

Loading…
취소
저장