import jwt
from datetime import datetime, timedelta
from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, PermissionsMixin
from django.conf import settings
from django.contrib.postgres.fields import ArrayField
The Question class defines the main storage point for questions. Each question has twelve fields:
class Questions(models.Model):
_id = models.TextField(primary_key=True, null=False)
prompt = models.TextField(null=False)
shuffleoption = models.BooleanField(null=False, default=False)
choices = ArrayField(models.TextField())
choiceanswers = ArrayField(models.BooleanField(default=False))
typename = models.TextField()
topic = models.ForeignKey('Topics', on_delete=models.PROTECT)
username = models.ForeignKey('Users', on_delete=models.PROTECT)
learningoutcome = ArrayField(models.TextField(null=False))
feedback = ArrayField(models.TextField(null=True), null=True)
draft = models.BooleanField(null=False)
hidden = models.BooleanField(null=False)
comments = ArrayField(models.TextField())
class Meta:
db_table = "questions"
class UserManager(BaseUserManager):
def create_user(self, username, email, password=None, student=False, professor=False):
if username is None:
raise TypeError('Users must have a username.')
if email is None:
raise TypeError('Users must have an email address.')
if password is None:
raise TypeError('Users must have a password')
user = self.model(username=username, email=self.normalize_email(email))
user.set_password(password)
user.contributor = True
user.student = student
user.professor = professor
user.save()
return user
def create_superuser(self, username, email, password):
if password is None:
raise TypeError('User requires password')
user = self.create_user(username, email, password)
user.admin = True
user.save()
return user
class Users(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address', unique=True, db_index=True)
username = models.TextField(primary_key=True)
active = models.BooleanField(default=True)
student = models.BooleanField(default=False)
salt = models.TextField()
contributor = models.BooleanField(default=True)
professor = models.BooleanField(default=False)
admin = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = UserManager()
def get_full_name(self):
return self.username
def __str__(self):
return self.email
@property
def token(self):
return self._generate_jwt_token()
def _generate_jwt_token(self):
dt = datetime.now() + timedelta(days=60)
token = jwt.encode({
'id': self.pk,
'exp': int(dt.strftime('%s'))
}, settings.SECRET_KEY, algorithm='HS256')
return token.decode('utf-8')
TODO
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
Model for Tags table in db tag: text field is used as primary key
@property
def is_student(self):
return self.student
@property
def is_professor(self):
return self.professor
@property
def is_admin(self):
return self.admin
def is_active(self):
return self.active
class Meta:
db_table = 'users'
The Tag class defines the main storage point for tags. Tags are used to tag topics.
Each tag has one field:
class Tags(models.Model):
tag = models.TextField(primary_key=True)
class Meta:
db_table = 'tags'
The Topic class defines the main storage point for topics.
Each topic has four fields:
class Topics(models.Model):
name = models.TextField(primary_key=True, null=False)
creator_id = models.ForeignKey('Users', on_delete=models.PROTECT)
learningoutcomes = ArrayField(models.TextField(null=False))
tags = ArrayField(models.TextField())
hidden = models.BooleanField(default=False, null=False)
class Meta:
db_table = 'topics'
The Review Quiz class defines the main storage point for completed quizzes that are generated by Students
Each review quiz has eight fields:
class ReviewQuiz(models.Model):
_id = models.TextField(primary_key=True)
questions = ArrayField(models.TextField())
answers = ArrayField(models.TextField())
correct = models.IntegerField(null=False, default=1)
total = models.IntegerField(null=False)
username = models.ForeignKey('Users', on_delete=models.PROTECT)
topic = models.ForeignKey('Topics', on_delete=models.PROTECT)
correctness = ArrayField(models.TextField())
class Meta:
db_table = 'quizzes'
class QuestionTags(models.Model):
qid = models.ForeignKey('Questions', on_delete=models.PROTECT)
tag = models.TextField(null=False)
class Meta:
db_table = 'questiontags'
Model for QuestionLearningOutcome table in db
class QuestionLearningOutCome(models.Model):
qid = models.ForeignKey(Questions, on_delete=models.PROTECT)
learningoutcome = models.TextField()
class Meta:
db_table = 'questionlearningoutcome'
class TopicLearningOutcome(models.Model):
topic = models.ForeignKey('Topics', on_delete=models.PROTECT)
learningoutcome = models.TextField(null=False)
class Meta:
db_table = 'topiclearningoutcome'
The TopComment class defines the main storage point for the top comments for questions. Each TopComment has five fields:
class TopComment(models.Model):
parentid = models.ForeignKey('Questions', on_delete=models.CASCADE)
commentid = models.TextField(primary_key=True)
comment = models.TextField(null=True)
user = models.ForeignKey('Users', on_delete=models.CASCADE)
date = models.DateTimeField()
class Meta:
db_table = 'topcomment'
The ChildComment class defines the main storage point for the child comments as TopComments. Each TopComment has five fields:
class ChildComment(models.Model):
parentid = models.ForeignKey('TopComment', on_delete=models.CASCADE)
id = models.TextField(primary_key=True)
comment = models.TextField(null=True)
user = models.ForeignKey('Users', on_delete=models.CASCADE)
date = models.DateTimeField()
class Meta:
db_table = 'childcomment'
The QuestionRating class defines the main storage point for ratings for a question. Each QuestionRating has three fields:
class QuestionRatings(models.Model):
qid = models.ForeignKey(Questions, on_delete=models.PROTECT)
username = models.ForeignKey(Users, on_delete=models.PROTECT)
rating = models.IntegerField()
class Meta:
db_table = 'questionratings'
unique_together = (("qid", "username"),)