Commit 2b6bc762e81b07833bd963bb6f45fddf6873c8b0
1 parent
4401f6495c
Exists in
master
expanded registration
Showing 6 changed files with 178 additions and 46 deletions Side-by-side Diff
flashcards/admin.py
View file @
2b6bc76
1 | 1 | from django.contrib import admin |
2 | 2 | from flashcards.models import Flashcard, UserFlashcard, Section, FlashcardMask, \ |
3 | - UserFlashcardReview | |
3 | + UserFlashcardReview, LecturePeriod, User | |
4 | +from simple_email_confirmation import EmailAddress | |
4 | 5 | |
5 | 6 | admin.site.register([ |
7 | + User, | |
6 | 8 | Flashcard, |
7 | 9 | FlashcardMask, |
8 | 10 | UserFlashcard, |
9 | 11 | UserFlashcardReview, |
10 | - Section | |
12 | + Section, | |
13 | + LecturePeriod | |
11 | 14 | ]) |
flashcards/api.py
View file @
2b6bc76
1 | +from django.contrib.auth import login, authenticate | |
1 | 2 | from django.core.mail import send_mail |
2 | 3 | from rest_framework.views import APIView |
3 | 4 | from rest_framework.response import Response |
... | ... | @@ -41,8 +42,8 @@ |
41 | 42 | raise ValidationError('Password is required') |
42 | 43 | |
43 | 44 | email = request.data['email'] |
44 | - user = User.objects.create_user(email) | |
45 | - | |
45 | + user = User.objects.create_user(email, email=email) | |
46 | + user.confirm_email(user.confirmation_key) | |
46 | 47 | body = ''' |
47 | 48 | Visit the following link to confirm your email address: |
48 | 49 | http://flashy.cards/app/verify_email/%s |
... | ... | @@ -54,6 +55,9 @@ |
54 | 55 | body % user.confirmation_key, |
55 | 56 | "noreply@flashy.cards", |
56 | 57 | [user.email]) |
58 | + user = authenticate(username=email, password=request.data['password']) | |
59 | + print user | |
60 | + login(request, user) | |
57 | 61 | |
58 | 62 | return Response(UserSerializer(User).data) |
flashcards/migrations/0001_initial.py
View file @
2b6bc76
1 | +# -*- coding: utf-8 -*- | |
2 | +from __future__ import unicode_literals | |
3 | + | |
4 | +from django.db import models, migrations | |
5 | +import django.contrib.auth.models | |
6 | +import django.utils.timezone | |
7 | +from django.conf import settings | |
8 | +import django.core.validators | |
9 | +import simple_email_confirmation.models | |
10 | + | |
11 | + | |
12 | +class Migration(migrations.Migration): | |
13 | + | |
14 | + dependencies = [ | |
15 | + ('auth', '0007_customuser_extensionuser'), | |
16 | + ] | |
17 | + | |
18 | + operations = [ | |
19 | + migrations.CreateModel( | |
20 | + name='User', | |
21 | + fields=[ | |
22 | + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), | |
23 | + ('password', models.CharField(max_length=128, verbose_name='password')), | |
24 | + ('last_login', models.DateTimeField(null=True, verbose_name='last login', blank=True)), | |
25 | + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), | |
26 | + ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, max_length=30, validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.', 'invalid')], help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', unique=True, verbose_name='username')), | |
27 | + ('first_name', models.CharField(max_length=30, verbose_name='first name', blank=True)), | |
28 | + ('last_name', models.CharField(max_length=30, verbose_name='last name', blank=True)), | |
29 | + ('email', models.EmailField(max_length=254, verbose_name='email address', blank=True)), | |
30 | + ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), | |
31 | + ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), | |
32 | + ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), | |
33 | + ('groups', models.ManyToManyField(related_query_name='user', related_name='user_set', to='auth.Group', blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', verbose_name='groups')), | |
34 | + ], | |
35 | + options={ | |
36 | + 'abstract': False, | |
37 | + 'verbose_name': 'user', | |
38 | + 'verbose_name_plural': 'users', | |
39 | + }, | |
40 | + bases=(models.Model, simple_email_confirmation.models.SimpleEmailConfirmationUserMixin), | |
41 | + managers=[ | |
42 | + (b'objects', django.contrib.auth.models.UserManager()), | |
43 | + ], | |
44 | + ), | |
45 | + migrations.CreateModel( | |
46 | + name='Flashcard', | |
47 | + fields=[ | |
48 | + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), | |
49 | + ('text', models.CharField(help_text=b'The text on the card', max_length=255)), | |
50 | + ('pushed', models.DateTimeField(help_text=b'When the card was first pushed', auto_now_add=True)), | |
51 | + ('material_date', models.DateTimeField(help_text=b'The date with which the card is associated')), | |
52 | + ('is_hidden', models.BooleanField(default=False)), | |
53 | + ('hide_reason', models.CharField(help_text=b'Reason for hiding this card', max_length=255, blank=True)), | |
54 | + ('author', models.ForeignKey(to=settings.AUTH_USER_MODEL)), | |
55 | + ], | |
56 | + options={ | |
57 | + 'ordering': ['-pushed'], | |
58 | + }, | |
59 | + ), | |
60 | + migrations.CreateModel( | |
61 | + name='FlashcardMask', | |
62 | + fields=[ | |
63 | + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), | |
64 | + ('ranges', models.CharField(max_length=255)), | |
65 | + ], | |
66 | + ), | |
67 | + migrations.CreateModel( | |
68 | + name='LecturePeriod', | |
69 | + fields=[ | |
70 | + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), | |
71 | + ('week_day', models.IntegerField(help_text=b'0-indexed day of week, starting at Monday')), | |
72 | + ('start_time', models.TimeField()), | |
73 | + ('end_time', models.TimeField()), | |
74 | + ], | |
75 | + ), | |
76 | + migrations.CreateModel( | |
77 | + name='Section', | |
78 | + fields=[ | |
79 | + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), | |
80 | + ('department', models.CharField(max_length=50)), | |
81 | + ('course_num', models.CharField(max_length=6)), | |
82 | + ('course_title', models.CharField(max_length=50)), | |
83 | + ('instructor', models.CharField(max_length=50)), | |
84 | + ('quarter', models.CharField(max_length=4)), | |
85 | + ], | |
86 | + options={ | |
87 | + 'ordering': ['-quarter'], | |
88 | + }, | |
89 | + ), | |
90 | + migrations.CreateModel( | |
91 | + name='UserFlashcard', | |
92 | + fields=[ | |
93 | + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), | |
94 | + ('pulled', models.DateTimeField(help_text=b'When the user pulled the card', null=True, blank=True)), | |
95 | + ('unpulled', models.DateTimeField(help_text=b'When the user unpulled this card', null=True, blank=True)), | |
96 | + ('flashcard', models.ForeignKey(to='flashcards.Flashcard')), | |
97 | + ('mask', models.ForeignKey(help_text=b"A mask which overrides the card's mask", to='flashcards.FlashcardMask')), | |
98 | + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), | |
99 | + ], | |
100 | + options={ | |
101 | + 'ordering': ['-pulled'], | |
102 | + }, | |
103 | + ), | |
104 | + migrations.CreateModel( | |
105 | + name='UserFlashcardReview', | |
106 | + fields=[ | |
107 | + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), | |
108 | + ('when', models.DateTimeField()), | |
109 | + ('blanked_word', models.CharField(help_text=b'The character range which was blanked', max_length=8, blank=True)), | |
110 | + ('response', models.CharField(help_text=b"The user's response", max_length=255, null=True, blank=True)), | |
111 | + ('correct', models.NullBooleanField(help_text=b"The user's self-evaluation of their response")), | |
112 | + ('user_flashcard', models.ForeignKey(to='flashcards.UserFlashcard')), | |
113 | + ], | |
114 | + ), | |
115 | + migrations.AlterUniqueTogether( | |
116 | + name='section', | |
117 | + unique_together=set([('department', 'course_num', 'quarter', 'instructor')]), | |
118 | + ), | |
119 | + migrations.AddField( | |
120 | + model_name='lectureperiod', | |
121 | + name='section', | |
122 | + field=models.ForeignKey(to='flashcards.Section'), | |
123 | + ), | |
124 | + migrations.AddField( | |
125 | + model_name='flashcard', | |
126 | + name='mask', | |
127 | + field=models.ForeignKey(blank=True, to='flashcards.FlashcardMask', help_text=b'The default mask for this card', null=True), | |
128 | + ), | |
129 | + migrations.AddField( | |
130 | + model_name='flashcard', | |
131 | + name='previous', | |
132 | + field=models.ForeignKey(blank=True, to='flashcards.Flashcard', help_text=b'The previous version of this card, if one exists', null=True), | |
133 | + ), | |
134 | + migrations.AddField( | |
135 | + model_name='flashcard', | |
136 | + name='section', | |
137 | + field=models.ForeignKey(help_text=b'The section with which the card is associated', to='flashcards.Section'), | |
138 | + ), | |
139 | + migrations.AddField( | |
140 | + model_name='user', | |
141 | + name='sections', | |
142 | + field=models.ManyToManyField(to='flashcards.Section'), | |
143 | + ), | |
144 | + migrations.AddField( | |
145 | + model_name='user', | |
146 | + name='user_permissions', | |
147 | + field=models.ManyToManyField(related_query_name='user', related_name='user_set', to='auth.Permission', blank=True, help_text='Specific permissions for this user.', verbose_name='user permissions'), | |
148 | + ), | |
149 | + migrations.AlterUniqueTogether( | |
150 | + name='userflashcard', | |
151 | + unique_together=set([('user', 'flashcard')]), | |
152 | + ), | |
153 | + migrations.AlterIndexTogether( | |
154 | + name='userflashcard', | |
155 | + index_together=set([('user', 'flashcard')]), | |
156 | + ), | |
157 | + ] |
flashcards/models.py
View file @
2b6bc76
1 | -from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin | |
1 | +from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin, AbstractUser | |
2 | 2 | from django.contrib.auth.tests.custom_user import CustomUser |
3 | 3 | from django.db.models import * |
4 | 4 | from simple_email_confirmation import SimpleEmailConfirmationUserMixin |
5 | 5 | |
6 | +# Hack to fix AbstractUser before subclassing it | |
7 | +AbstractUser._meta.get_field('email')._unique = True | |
6 | 8 | |
7 | -class UserManager(BaseUserManager): | |
8 | - def create_user(self, email, password=None): | |
9 | - """ | |
10 | - Creates and saves a User with the given email, date of | |
11 | - birth and password. | |
12 | - """ | |
13 | - if not email: | |
14 | - raise ValueError('Users must have an email address') | |
15 | - | |
16 | - user = self.model(email=self.normalize_email(email)) | |
17 | - | |
18 | - user.set_password(password) | |
19 | - user.save(using=self._db) | |
20 | - return user | |
21 | - | |
22 | - def create_superuser(self, email, password): | |
23 | - """ | |
24 | - Creates and saves a superuser with the given email and password. | |
25 | - """ | |
26 | - user = self.create_user(email, password=password) | |
27 | - user.is_staff = True | |
28 | - user.save(using=self._db) | |
29 | - return user | |
30 | - | |
31 | - | |
32 | -class User(AbstractBaseUser, SimpleEmailConfirmationUserMixin, ): | |
9 | +class User(AbstractUser, SimpleEmailConfirmationUserMixin, ): | |
33 | 10 | USERNAME_FIELD = 'email' |
34 | 11 | REQUIRED_FIELDS = [] |
35 | - | |
36 | - objects = UserManager() | |
37 | - is_staff = BooleanField(default=False) | |
38 | - | |
39 | - email = EmailField( | |
40 | - verbose_name='email address', | |
41 | - max_length=255, | |
42 | - unique=True, | |
43 | - ) | |
44 | - date_joined = DateTimeField(auto_now_add=True) | |
45 | 12 | sections = ManyToManyField('Section') |
46 | 13 | |
47 | 14 | |
... | ... | @@ -52,7 +19,7 @@ |
52 | 19 | 2. A user used to have a flashcard in their deck |
53 | 20 | 3. A user has a flashcard hidden from them |
54 | 21 | """ |
55 | - user = ForeignKey(User) | |
22 | + user = ForeignKey('User') | |
56 | 23 | mask = ForeignKey('FlashcardMask', help_text="A mask which overrides the card's mask") |
57 | 24 | pulled = DateTimeField(blank=True, null=True, help_text="When the user pulled the card") |
58 | 25 | flashcard = ForeignKey('Flashcard') |
flashcards/serializers.py
View file @
2b6bc76
flashy/settings.py
View file @
2b6bc76