aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWeitian LI <liweitianux@gmail.com>2014-04-27 02:02:15 +0800
committerWeitian LI <liweitianux@gmail.com>2014-04-27 02:02:15 +0800
commit823ae2dcf72db5e739c3d96426d1985a79a617cf (patch)
tree6e242a662a325c65b621cbd9c30d18b85ca3259a
parent9172b7f08a7dabde275253b47ad051600decbe7b (diff)
downloaddjango-skaschool-823ae2dcf72db5e739c3d96426d1985a79a617cf.tar.bz2
* added model 'UserFile' and register to admin
* updated 'UserProfile' model: o added fields 'reason', 'transcript', 'supplement' o used 'ContentTypeRestrictedFileField' with dynamical 'upload_to' * updated 'UpdateProfileView' to support formset * updated 'UpdateProfileForm' with new fields and clean method * added 'UserFileForm' and 'UserFileFormSet'
-rw-r--r--account/admin.py3
-rw-r--r--account/forms.py64
-rw-r--r--account/models.py65
-rw-r--r--account/views.py45
4 files changed, 164 insertions, 13 deletions
diff --git a/account/admin.py b/account/admin.py
index b5ec5b6..ee568fc 100644
--- a/account/admin.py
+++ b/account/admin.py
@@ -2,9 +2,10 @@
from django.contrib import admin
-from account.models import UserProfile
+from account.models import UserProfile, UserFile
admin.site.register(UserProfile)
+admin.site.register(UserFile)
diff --git a/account/forms.py b/account/forms.py
index c7e15d3..cb0b6b2 100644
--- a/account/forms.py
+++ b/account/forms.py
@@ -5,6 +5,7 @@ account/forms.py for skaschool
"""
from django import forms
+from django.forms.models import inlineformset_factory
from django.contrib.auth.models import User
from django.contrib.sites.models import Site, RequestSite
from django.utils.translation import ugettext_lazy as _
@@ -12,7 +13,7 @@ from django.utils.translation import ugettext_lazy as _
from registration.forms import RegistrationFormUniqueEmail
from captcha.fields import ReCaptchaField
-from account.models import UserProfile
+from account.models import UserProfile, UserFile
class UserRegForm(RegistrationFormUniqueEmail):
@@ -104,6 +105,65 @@ class UpdateProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
- fields = ('realname', 'gender', 'institute', 'identify')
+ fields = (
+ 'user',
+ 'realname',
+ 'gender',
+ 'institute',
+ 'identify',
+ 'reason',
+ 'transcript',
+ 'supplement',
+ )
+ widgets = {
+ 'user': forms.HiddenInput,
+ }
+
+ def __init__(self, *args, **kwargs):
+ super(UpdateProfileForm, self).__init__(*args, **kwargs)
+ # reorder fields, append 'email' just after 'realname'
+ self.fields.keyOrder = [
+ 'user',
+ 'realname',
+ 'email',
+ 'gender',
+ 'institute',
+ 'identify',
+ 'reason',
+ 'transcript',
+ 'supplement',
+ ]
+ def clean(self):
+ """
+ check if 'transcript' is needed and provided
+ """
+ form_data = self.cleaned_data
+ user = form_data.get('user')
+ profile = user.userprofile_set.get(user=user)
+ profile.identify = form_data.get('identify', profile.identify)
+ transcript = self.cleaned_data.get('transcript', False)
+ if (profile.is_transcript_required() and (not transcript)):
+ raise forms.ValidationError(_("Transcript is required."), code='required')
+ # not save 'profile' here
+ return self.cleaned_data
+
+
+class UserFileForm(forms.ModelForm):
+ """
+ form of UserFile, empty_permitted=True
+ """
+ class Meta:
+ model = UserFile
+
+ def __init__(self, *args, **kwargs):
+ super(UserFileForm, self).__init__(*args, **kwargs)
+ self.empty_permitted = True
+
+
+### formset ###
+# UserFileFormSet: parent_model -> User
+UserFileFormSet = inlineformset_factory(User,
+ UserFile, form=UserFileForm,
+ extra=1, can_delete=True)
diff --git a/account/models.py b/account/models.py
index f3f12f8..257477d 100644
--- a/account/models.py
+++ b/account/models.py
@@ -6,12 +6,15 @@
from django.db import models
from django.contrib.auth.models import User
-
+from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from registration.signals import user_registered
+from account.extra import ContentTypeRestrictedFileField
+
+###### account models ######
class UserProfile(models.Model):
"""
custom user profile
@@ -38,7 +41,8 @@ class UserProfile(models.Model):
# choices for identify
IDENTIFIES = (
('OT', _("Other")),
- ('UG', _("Undergraudate")),
+ ('UG', _("Undergraudate (junior and below)")),
+ ('U4', _("Undergraudate (senior)")),
('MG', _("Master graudate")),
('PG', _("PhD graudate")),
('PD', _("Post-doctoral")),
@@ -53,11 +57,21 @@ class UserProfile(models.Model):
)
# model fields
# FK default backward manager name 'userprofile_set'
- user = models.ForeignKey(User, unique=True, verbose_name=_("Username"))
+ user = models.ForeignKey(User, unique=True, verbose_name=_("User"))
realname = models.CharField(_("Name"), max_length=30)
gender = models.CharField(_("Gender"), max_length=1, choices=GENDERS)
institute = models.CharField(_("Institute"), max_length=100)
- identify = models.CharField(_("Identify"), max_length=2, choices=IDENTIFIES)
+ identify = models.CharField(_("Identify"), max_length=2,
+ choices=IDENTIFIES)
+ # reasons to participate
+ reason = models.TextField(_("Why attend"))
+ # transcript: needed if undergraudate (junior and below)
+ transcript = ContentTypeRestrictedFileField(upload_to=lambda instance, filename: u'account/{0}/{1}'.format(instance.user.username, filename),
+ verbose_name=_("Transcript"), blank=True, null=True,
+ content_types=settings.ALLOWED_CONTENT_TYPES,
+ max_upload_size=settings.ALLOWED_MAX_UPLOAD_SIZE)
+ # supplement: record additional information
+ supplement = models.TextField(_("Supplement"), blank=True)
# store the infomation about approval and sponsorship
is_approved = models.CharField(_("Is approved"), max_length=1,
choices=APPROVED_STATUS, default='C')
@@ -69,7 +83,17 @@ class UserProfile(models.Model):
verbose_name_plural = _('user profiles')
def __unicode__(self):
- return u'UserProfile for %s' % self.user
+ return u'UserProfile for %s' % self.user.username
+
+ def is_transcript_required(self):
+ """
+ if 'identify' is UG (undergraduate junior and below); then
+ transcript is required, return True. Otherwise, return False
+ """
+ if (self.identify == 'UG'):
+ return True
+ else:
+ return False
def get_approved(self, *args, **kwargs):
"""
@@ -111,6 +135,37 @@ class UserProfile(models.Model):
identifies_dict = dict((k, v) for k, v in self.IDENTIFIES)
return identifies_dict.get(self.identify)
+ def get_userfiles(self):
+ """
+ return the UserFile objects related to this user
+ NOTE: transcript is not included here.
+ """
+ return self.user.userfile_set.all()
+
+
+class UserFile(models.Model):
+ """
+ model to deal with user uploaded files
+ """
+ user = models.ForeignKey(User, verbose_name=_("User"))
+ title = models.CharField(_("Title"), max_length=100)
+ description = models.TextField(_("Description"), blank=True)
+ file = ContentTypeRestrictedFileField(upload_to=lambda instance, filename: u'account/{0}/{1}'.format(instance.user.username, filename),
+ verbose_name=_("File"),
+ content_types=settings.ALLOWED_CONTENT_TYPES,
+ max_upload_size=settings.ALLOWED_MAX_UPLOAD_SIZE)
+ created_at = models.DateTimeField(_("Created time"),
+ auto_now_add=True)
+ modified_at = models.DateTimeField(_("Modified time"), auto_now=True)
+
+ class Meta:
+ verbose_name = _('user file')
+ verbose_name_plural = _('user files')
+ ordering = ['user', 'id']
+
+ def __unicode__(self):
+ return u'UserFile of %s: %s' % (self.user.username, self.title)
+
###### signal callback ######
def user_registered_callback(sender, user, request, **kwargs):
diff --git a/account/views.py b/account/views.py
index a4c3337..432a8fc 100644
--- a/account/views.py
+++ b/account/views.py
@@ -12,7 +12,7 @@ from django.core.urlresolvers import reverse_lazy
from django.http import HttpResponseRedirect
from account.models import UserProfile
-from account.forms import ResendEmailForm, UpdateProfileForm
+from account.forms import ResendEmailForm, UpdateProfileForm, UserFileFormSet
###### Class-based views ######
@@ -60,7 +60,8 @@ class UpdateProfileView(UpdateView):
def get(self, request, *args, **kwargs):
"""
- Returns the keyword arguments for instantiating the form.
+ Returns the keyword arguments for instantiating the form
+ and related formsets.
modify this method to add 'email' data
"""
self.object = self.get_object()
@@ -69,18 +70,52 @@ class UpdateProfileView(UpdateView):
# initialize form 'email' field
user = self.request.user
form.fields['email'].initial = user.email
- return self.render_to_response(self.get_context_data(form=form))
+ # formset
+ formset = UserFileFormSet()
+ return self.render_to_response(
+ self.get_context_data(form=form, formset=formset))
- def form_valid(self, form):
+ def post(self, request, *args, **kwargs):
+ """
+ handle POST requests, instantiating a form instance and
+ related formset with passed POST data and then validate.
+ """
+ self.object = self.get_object()
+ form_class = self.get_form_class()
+ form = self.get_form(form_class)
+ # formset
+ formset = UserFileFormSet(self.request.POST, self.request.FILES)
+ user = self.request.user
+ # set instance for formset first, otherwise cannot generate
+ # right upload_to due to the empty of user
+ formset.instance = user # UserFileFormSet parent_model
+ if (form.is_valid() and formset.is_valid()):
+ return self.form_valid(form, formset)
+ else:
+ return self.form_invalid(form, formset)
+
+ def form_valid(self, form, formset):
"""
modify 'form_valid' to update email field
"""
form_data = form.cleaned_data
+ # save object
+ self.object = form.save()
# update email and save
user = self.request.user
user.email = form_data.get('email', user.email)
user.save()
- return super(UpdateProfileView, self).form_valid(form)
+ # formset
+ formset.instance = user # UserFileFormSet parent_model
+ formset.save()
+ return HttpResponseRedirect(self.get_success_url())
+
+ def form_invalid(self, form, formset):
+ """
+ re-render the context data with the data-filled forms and errors
+ """
+ return self.render_to_response(
+ self.get_context_data(form=form, formset=formset))
class ListApprovedView(ListView):