Commit d6a663553957fa87b9715b4f75f5bfb4afb551ba

Authored by Andrew Buss
1 parent 86fde4fa00
Exists in master

Fixed up some model errors, added docstrings to some

Showing 2 changed files with 195 additions and 36 deletions Side-by-side Diff

flashcards/migrations/0003_auto_20150429_0344.py View file @ d6a6635
  1 +# -*- coding: utf-8 -*-
  2 +from __future__ import unicode_literals
  3 +
  4 +from django.db import models, migrations
  5 +
  6 +
  7 +class Migration(migrations.Migration):
  8 +
  9 + dependencies = [
  10 + ('flashcards', '0002_auto_20150429_0248'),
  11 + ]
  12 +
  13 + operations = [
  14 + migrations.AlterModelOptions(
  15 + name='class',
  16 + options={'ordering': ['-quarter']},
  17 + ),
  18 + migrations.AlterModelOptions(
  19 + name='flashcard',
  20 + options={'ordering': ['-pushed']},
  21 + ),
  22 + migrations.RenameField(
  23 + model_name='class',
  24 + old_name='professor',
  25 + new_name='instructor',
  26 + ),
  27 + migrations.RemoveField(
  28 + model_name='flashcard',
  29 + name='hidden',
  30 + ),
  31 + migrations.AddField(
  32 + model_name='flashcard',
  33 + name='hide_reason',
  34 + field=models.CharField(help_text=b'Reason for hiding this card', max_length=255, blank=True),
  35 + ),
  36 + migrations.AddField(
  37 + model_name='flashcard',
  38 + name='is_hidden',
  39 + field=models.BooleanField(default=False),
  40 + ),
  41 + migrations.AlterField(
  42 + model_name='flashcard',
  43 + name='associated_class',
  44 + field=models.ForeignKey(help_text=b'The class with which the card is associated', to='flashcards.Class'),
  45 + ),
  46 + migrations.AlterField(
  47 + model_name='flashcard',
  48 + name='mask',
  49 + field=models.ForeignKey(blank=True, to='flashcards.FlashcardMask', help_text=b'The default mask for this card', null=True),
  50 + ),
  51 + migrations.AlterField(
  52 + model_name='flashcard',
  53 + name='material_date',
  54 + field=models.DateTimeField(help_text=b'The date with which the card is associated'),
  55 + ),
  56 + migrations.AlterField(
  57 + model_name='flashcard',
  58 + name='previous',
  59 + field=models.ForeignKey(blank=True, to='flashcards.Flashcard', help_text=b'The previous version of this card, if one exists', null=True),
  60 + ),
  61 + migrations.AlterField(
  62 + model_name='flashcard',
  63 + name='pushed',
  64 + field=models.DateTimeField(help_text=b'When the card was first pushed', auto_now_add=True),
  65 + ),
  66 + migrations.AlterField(
  67 + model_name='flashcard',
  68 + name='text',
  69 + field=models.CharField(help_text=b'The text on the card', max_length=255),
  70 + ),
  71 + migrations.AlterField(
  72 + model_name='userflashcard',
  73 + name='mask',
  74 + field=models.ForeignKey(help_text=b"A mask which overrides the card's mask", to='flashcards.FlashcardMask'),
  75 + ),
  76 + migrations.AlterField(
  77 + model_name='userflashcard',
  78 + name='pulled',
  79 + field=models.DateTimeField(help_text=b'When the user pulled the card', null=True, blank=True),
  80 + ),
  81 + migrations.AlterField(
  82 + model_name='userflashcard',
  83 + name='unpulled',
  84 + field=models.DateTimeField(help_text=b'When the user unpulled this card', null=True, blank=True),
  85 + ),
  86 + migrations.AlterField(
  87 + model_name='userflashcardreview',
  88 + name='blanked_word',
  89 + field=models.CharField(help_text=b'The character range which was blanked', max_length=8, blank=True),
  90 + ),
  91 + migrations.AlterField(
  92 + model_name='userflashcardreview',
  93 + name='correct',
  94 + field=models.NullBooleanField(help_text=b"The user's self-evaluation of their response"),
  95 + ),
  96 + migrations.AlterField(
  97 + model_name='userflashcardreview',
  98 + name='response',
  99 + field=models.CharField(help_text=b"The user's response", max_length=255, null=True, blank=True),
  100 + ),
  101 + migrations.AlterUniqueTogether(
  102 + name='class',
  103 + unique_together=set([('department', 'course_num', 'quarter', 'instructor')]),
  104 + ),
  105 + ]
flashcards/models.py View file @ d6a6635
1 1 from django.contrib.auth.models import User
2   -from django.db import models
  2 +from django.db.models import *
3 3  
4 4  
5   -class UserFlashcard(models.Model):
  5 +class UserFlashcard(Model):
6 6 """
7 7 Represents the relationship between a user and a flashcard by:
8 8 1. A user has a flashcard in their deck
9 9 2. A user used to have a flashcard in their deck
10 10 3. A user has a flashcard hidden from them
11 11 """
12   - user = models.ForeignKey(User)
13   - mask = models.ForeignKey('FlashcardMask')
14   - pulled = models.DateTimeField(null=True)
15   - flashcard = models.ForeignKey('Flashcard')
16   - unpulled = models.DateTimeField(null=True)
  12 + user = ForeignKey(User)
  13 + mask = ForeignKey('FlashcardMask', help_text="A mask which overrides the card's mask")
  14 + pulled = DateTimeField(blank=True, null=True, help_text="When the user pulled the card")
  15 + flashcard = ForeignKey('Flashcard')
  16 + unpulled = DateTimeField(blank=True, null=True, help_text="When the user unpulled this card")
17 17  
18 18 class Meta:
  19 + # There can be at most one UserFlashcard for each User and Flashcard
19 20 unique_together = (('user', 'flashcard'),)
20 21 index_together = ["user", "flashcard"]
  22 + # By default, order by most recently pulled
21 23 ordering = ['-pulled']
22 24  
23 25 def is_hidden(self):
  26 + """
  27 + A card is hidden only if a user has not ever added it to their deck.
  28 + :return: Whether the flashcard is hidden from the user
  29 + """
24 30 return not self.pulled
25 31  
26   - def is_active(self):
  32 + def is_in_deck(self):
  33 + """
  34 + :return:Whether the flashcard is in the user's deck
  35 + """
27 36 return self.pulled and not self.unpulled
28 37  
29 38  
30   -class FlashcardMask(models.Model):
31   - ranges = models.CharField(max_length=255)
  39 +class FlashcardMask(Model):
  40 + """
  41 + A serialized list of character ranges that can be blanked out during review.
  42 + This is encoded as '13-145,150-195'
  43 + """
  44 + ranges = CharField(max_length=255)
32 45  
33 46  
34   -class Flashcard(models.Model):
35   - text = models.CharField(max_length=255)
36   - associated_class = models.ForeignKey('Class')
37   - pushed = models.DateTimeField()
38   - material_date = models.DateTimeField()
39   - previous = models.ForeignKey('Flashcard', null=True)
40   - author = models.ForeignKey(User)
41   - hidden = models.CharField(null=True, blank=True, max_length=255)
42   - mask = models.ForeignKey(FlashcardMask, null=True)
  47 +class Flashcard(Model):
  48 + text = CharField(max_length=255, help_text='The text on the card')
  49 + associated_class = ForeignKey('Class', help_text='The class with which the card is associated')
  50 + pushed = DateTimeField(auto_now_add=True, help_text="When the card was first pushed")
  51 + material_date = DateTimeField(help_text="The date with which the card is associated")
  52 + previous = ForeignKey('Flashcard', null=True, blank=True,
  53 + help_text="The previous version of this card, if one exists")
  54 + author = ForeignKey(User)
  55 + is_hidden = BooleanField(default=False)
  56 + hide_reason = CharField(blank=True, max_length=255, help_text="Reason for hiding this card")
  57 + mask = ForeignKey(FlashcardMask, blank=True, null=True, help_text="The default mask for this card")
43 58  
44   - def is_visible_to(self, user):
45   - result = self.userflashcard_set.filter(user=user)
  59 + class Meta:
  60 + # By default, order by most recently pushed
  61 + ordering = ['-pushed']
46 62  
  63 + def is_hidden_from(self, user):
  64 + """
  65 + A card can be hidden globally, but if a user has the card in their deck,
  66 + this visibility overrides a global hide.
  67 + :param user:
  68 + :return: Whether the card is hidden from the user.
  69 + """
  70 + result = user.userflashcard_set.filter(flashcard=self)
  71 + if not result.exists(): return self.is_hidden
  72 + return result[0].is_hidden()
  73 +
  74 +
47 75 @classmethod
48 76 def cards_visible_to(cls, user):
49   - return cls.objects.filter(hidden=False).exclude(userflashcard=user,
50   - userflashcard__pulled=None)
  77 + """
  78 + :param user:
  79 + :return: A queryset with all cards that should be visible to a user.
  80 + """
  81 + return cls.objects.filter(hidden=False).exclude(userflashcard=user, userflashcard__pulled=None)
51 82  
52 83  
53   -class UserFlashcardReview(models.Model):
54   - user_flashcard = models.ForeignKey(UserFlashcard)
55   - when = models.DateTimeField()
56   - blanked_word = models.CharField(max_length=8)
57   - response = models.CharField(max_length=255, blank=True, null=True)
58   - correct = models.NullBooleanField()
  84 +class UserFlashcardReview(Model):
  85 + """
  86 + An event of a user reviewing a flashcard.
  87 + """
  88 + user_flashcard = ForeignKey(UserFlashcard)
  89 + when = DateTimeField()
  90 + blanked_word = CharField(max_length=8, blank=True, help_text="The character range which was blanked")
  91 + response = CharField(max_length=255, blank=True, null=True, help_text="The user's response")
  92 + correct = NullBooleanField(help_text="The user's self-evaluation of their response")
59 93  
  94 + def status(self):
  95 + """
  96 + There are three stages of a review object:
  97 + 1. the user has been shown the card
  98 + 2. the user has answered the card
  99 + 3. the user has self-evaluated their responses's correctness
  100 + :return: string (evaluated, answered, viewed)
  101 + """
  102 + if self.correct != None: return "evaluated"
  103 + if self.response: return "answered"
  104 + return "viewed"
60 105  
61   -class Class(models.Model):
62   - department = models.CharField(max_length=50)
63   - course_num = models.IntegerField()
64   - name = models.CharField(max_length=50)
65   - professor = models.CharField(max_length=50)
66   - quarter = models.CharField(max_length=4)
67   - members = models.ManyToManyField(User)
  106 +
  107 +class Class(Model):
  108 + """
  109 + A UCSD course taught by an instructor during a quarter.
  110 + Different sections taught by the same instructor in the same quarter are considered identical.s
  111 + """
  112 + department = CharField(max_length=50)
  113 + course_num = IntegerField()
  114 + name = CharField(max_length=50)
  115 + instructor = CharField(max_length=50)
  116 + quarter = CharField(max_length=4)
  117 + members = ManyToManyField(User)
  118 +
  119 + class Meta:
  120 + unique_together = (('department', 'course_num', 'quarter', 'instructor'),)
  121 + ordering = ['-quarter']