This is the current iteration of my first model of a Person. The model is populated by a survey application using forms.ModelForm
and a SessionWizardView
which splits the survey over multiple pages
Would anybody be able to tell me if I am making any obvious mistakes? Any advice or efficiencies are much appreciated. I am completely self thought is even very obvious things to most developers might not be very obvious to me.
models.py
from django import forms
from django.forms import ModelForm
from django.db import models
import datetime
from django.core.exceptions import ValidationError
from multiselectfield import MultiSelectField
class Person(models.Model):
# These take the value of a jQuery Slider Bar
instruction_task_one_value = models.SmallIntegerField(null=True, blank=True, max_length=1000)
instruction_task_two_value = models.SmallIntegerField(null=True, blank=True, max_length=1000)
start = models.CharField(null=True, max_length=100, blank=True)
spike_one_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
slider_one_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
slider_two_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
slider_three_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
DV_one_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
DV_two_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
DV_three_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
slider_four_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
slider_five_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
slider_six_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
DV_four_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
DV_five_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
DV_six_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
spike_two_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
slider_seven_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
slider_eight_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
slider_nine_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
DV_seven_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
DV_eight_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
DV_nine_value = models.SmallIntegerField(null=True, max_length=100, blank=True)
sender = models.EmailField(null=True, blank=True, verbose_name='What is your email address?')
birthdate = models.DateField(null=True, blank=True) #overwritten in forms.py so passed no more arguments
SEX = (
('MALE', 'Male'),
('FEMALE', 'Female'))
sex = models.CharField(null=True, blank=True, max_length=100, choices=SEX, verbose_name='What sex are you?')
RELATIONSHIP = (
('SINGLE', "Single"),
('INARELATIONSHIP', "In a relationship"),
('MARRIED', "Married"),
('DIVORCED', "Divorced"),
('SEPARATED', "Separated"),
('WIDOWED', "Widowed"),)
relationship = models.CharField(null=True, blank=True, max_length=100, choices=RELATIONSHIP, verbose_name='What is your relationship status?')
STATE = (
('ALABAMA', 'Alabama'),
('ALASKA', 'Alaska'),
('ARIZONA', 'Arizona'),
('ARKANSAS', 'Arkansas'),
('CALIFORNIA', 'California'),
('COLORADO', 'Colorado'),
('CONNECTICUT', 'Connecticut'),
('DELAWARE', 'Delaware'),
('FLORIDA', 'Florida'),
('GEORGIA', 'Georgia'),
('HAWAII', 'Hawaii'),
('IDAHO', 'Idaho'),
('ILLINOIS', 'Illinois'),
('INDIANA', 'Indiana'),
('IOWA', 'Iowa'),
('KANSAS', 'Kansas'),
('KENTUCKY', 'Kentucky'),
('LOUISIANA', 'Louisiana'),
('MAINE', 'Maine'),
('MARYLAND', 'Maryland'),
('MASSACHUSETTS', 'Massachusetts'),
('MICHIGAN', 'Michigan'),
('MINNESOTA', 'Minnesota'),
('MISSISSIPPI', 'Mississippi'),
('MISSOURI', 'Missouri'),
('MONTANA', 'Montana'),
('NEBRASKA', 'Nebraska'),
('NEVADA', 'Nevada'),
('NEW_HAMPSHIRE', 'New Hampshire'),
('NEW_JERSEY', 'New Jersey'),
('NEW_MEXICO', 'New Mexico'),
('NEW_YORK', 'New York'),
('NORTH_CAROLINA', 'North Carolina'),
('NORTH_DAKOTA', 'North Dakota'),
('OHIO', 'Ohio'),
('OKLAHOMA', 'Oklahoma'),
('OREGON', 'Oregon'),
('PENNSYLVANIA', 'Pennsylvania'),
('RHODE_ISLAND', 'Rhode Island'),
('SOUTH_CAROLINA', 'South Carolina'),
('SOUTH_DAKOTA', 'South Dakota'),
('TENNESSEE', 'Tennessee'),
('TEXAS', 'Texas'),
('UTAH', 'Utah'),
('VERMONT', 'Vermont'),
('VIRGINIA', 'Virginia'),
('WASHINGTON', 'Washington'),
('WEST_VIRGINIA', 'West Virginia'),
('WISCONSIN', 'Wisconsin'),
('WYOMING', 'Wyoming'),
('DISTRICT_OF_COLUMBIA', 'District of Columbia'),
('PUERTO_RICO', 'Puerto Rico'),
('GUAM', 'Guam'),
('AMERICAN_SAMOA', 'American Samoa'),
('US_VIRGIN_ISLANDS', 'US Virgin Islands'),
('NORTHERN_MARIANO_ISLANDS', 'Northern Mariana Islands'),)
state = models.CharField(null=True, blank=True, max_length=100, choices=STATE, verbose_name='What State are you from?')
INTERNET_USAGE = (
('INTERNET_LESS_THAN_ONE_HOUR_A_DAY', 'Less than one hour a day'),
('INTERNET_ONE_TO_TWO_HOURS_A_DAY', '1 - 2 hours a day'),
('INTERNET_TWO_TO_FOUR_HOURS_A_DAY', '2 - 4 hours a day'),
('INTERNET_FOUR_TO_SIX_HOURS_A_DAY', '4 - 6 hours a Day'),
('INTERNET_SIX_TO_EIGHT_HOURS_A_DAY', '6 - 8 hours a day'),
('INTERNET_EIGHT_PLUS_HOURS_A_DAY', '8 + hours a day'), )
internet_usage = models.CharField(null=True, blank=True, max_length=100, default=None, choices=INTERNET_USAGE)
SMART_PHONE_OWNERSHIP = (
('YES_SMARTPHONE', 'Yes'),
('NO_SMARTPHONE', 'No'),)
smart_phone_ownership = models.CharField(null=True, max_length=100, blank=True, choices=SMART_PHONE_OWNERSHIP, verbose_name='Do you own a Smartphone?')
SMART_PHONE_USAGE = (
('SMART_PHONE_LESS_THAN_ONE_HOUR_A_DAY', 'Less than one hour a day'),
('SMART_PHONE_ONE_TO_TWO_HOURS_A_DAY', '1 - 2 Hours a day'),
('SMART_PHONE_TWO_TO_FOUR_HOURS_A_DAY', '2 - 4 hours a day'),
('SMART_PHONE_FOUR_TO_SIX_HOURS_A_DAY', '4 - 6 hours a Day'),
('SMART_PHONE_SIX_TO_EIGHT_HOURS_A_DAY', '6 - 8 hours a day'),
('SMART_PHONE_EIGHT_PLUS_HOURS_A_DAY', '8 + hours a day'),)
smart_phone_usage = models.CharField(null=True, max_length=100, default=None, choices=SMART_PHONE_USAGE, verbose_name='If Yes, How many hours a day do you access the Internet on it?')
EDUCATION = (
('ELEMENTARY_SCHOOL_ONLY', 'Elementary school only'),
('SOME_HIGH_SCHOOL_BUT_DID_NOT_FINISH', 'Some high school, but did not finish'),
('COMPLETED_HIGH_SCHOOL', 'Completed high school'),
('SOME_COLLEGE_BUT_DID_NOT_FINISH', 'Some college, but did not finish'),
('TWO_YEAR_COLLEGE_DEGREE', 'Two-year college degree / A.A / A.S.'),
('FOUR_YEAR_COLLEGE_DEGREE_BA_BS', 'Four-year college degree / B.A. / B.S.'),
('SOME_GRADUATE_STUDY', 'Some graduate study'),
('COMPLEATED_MASTERS_OR_PROFESSIONAL_DEGREE', 'Completed Masters or professional degree'),
('ADVANCED_GRADUATE_STUDY_OR_PHD', 'Advanced Graduate study or Ph.D.'),
('OTHR', 'Other'), )
education = models.CharField(null=True, max_length=100, default=None, choices=EDUCATION, verbose_name='What is the highest level of education you have completed?')
WAGES = (
('UNDER_S10000', 'Under $10,000'),
('S10000_S19999', '$10,000 - $19,999'),
('S20000_S29999', '$20,000 - $29,999'),
('S30000_S39999', '$30,000 - $39,999'),
('S40000_S49999', '$40,000 - $49,999'),
('S50000_S59999', '$50,000 - $59,999'),
('S60000_S69000', '$60,000 - $69,999'),
('S70000_S79000', '$70,000 - $79,999'),
('S80000_S89999', '$80,000 - $89,999'),
('S90000_S99000', '$90,000 - $99,999'),
('OVER_100000', 'Over $100,000'), )
wages = models.CharField(null=True, max_length=100, default=None, choices=WAGES, verbose_name='What is your expected income range for 2014?')
PRESENTAGE_SAVINGS = (
('ZERO', '0%'),
('ZERO_FIVE', '0% - 5%'),
('FIVE_TEN', '5% - 10%'),
('TEN_FIFTEEN', '10% - 15%'),
('FIFTEEN_TWENTY', '15% - 20%'),
('TWENTY_TWENTYFIVE', '20% - 25%'),
('TWENTYFIVE_THIRTY', '25% - 30%'),
('THIRTY_THIRTYFIVE', '30% - 35%'),
('THIRTYFIVE_FORTY', '35% - 40%'),
('FORTY_FORTYFIVE', '40% - 45%'),
('FORTYFIVE_FIFTY', '45% - 50%'),
('FIFTY_PLUS', '50%+'),)
presentage_savings = models.CharField(null=True, max_length=100, default=None, choices=PRESENTAGE_SAVINGS, verbose_name='What proportion of your weekly/monthly income do you save?')
OCCUPATION = (
('HOME_PARENT', 'Stay at home Parent'),
('UNEMPLOYED', 'Unemployed'),
('PROFESSIONAL', 'Professional'),
('SEMI_PROFESSIONAL', 'Semi-professional'),
('SKILLED_PROFESSIONAL', 'Skilled professional'),
('SKILLED_MANUAL', 'Skilled manual'),
('SEMI_SKILLED_MANUAL', 'Semi-skilled manual'),
('UNSKILLED_MANUAL', ' Unskilled manual'),
('OTHER', 'Other') )
occupation = models.CharField(null=True, max_length=100, default=None, choices=OCCUPATION, verbose_name='Which best describes your current occupation?')
LIVING = (
('RENT_ALONE', 'Rent alone'),
('REST_MULTIPLE_OCCUPANCY', 'Rent in multiple occupancy'),
('DORMITORY', 'Dormitory'),
('OWN_HOME_WITH_MORTGUAGE', 'Own home, with mortgage'),
('OWEN_HOME_NO_MORTGUAGE', 'Own home, no mortgage'),
('LIVING_WITH_FAMILY', 'Living with family'),
('NO_PERMANENT_LIVING_ADDRESS', 'No permanent living address'),
('OTHER', 'Other'),)
living = models.CharField(null=True, max_length=100, default=None, choices = LIVING, verbose_name = 'What are your current living arrangements?')
LIBERAL_CONSERVATIVE = (
('STRONG_LIBERAL', 'Strong Liberal'),
('NOT_SO_STRONG_LIBERAL', 'Not so strong Liberal'),
('INDEPENDENT_LEANING_LIBERAL', 'Independent leaning Liberal'),
('INDEPENDENT', 'Independent'),
('INDEPENDENT_LEANING_CONSERVATIVE', 'Independent leaning Conservative'),
('NOT_SO_STRONG_CONSERVATIVE', 'Not so strong Conservative'),
('STRONG_CONSERVATIVE', 'Strong Conservative'),
('OTHER', 'Other'),
('DONT_KNOW', "Don't know"), )
liberal_conservative = models.CharField(null=True, max_length=100, default=None, choices = LIBERAL_CONSERVATIVE, verbose_name = 'What most closely describes your political viewpoint?')
DEMOCRAT_REPUBLICAN = (
('STRONG_LIBERAL', 'Strong Democrat'),
('NOT_SO_STRONG_LIBERAL', 'Not so strong Democrat'),
('INDEPENDENT_LEANING_LIBERAL', 'Independent leaning Democrat'),
('INDEPENDENT', 'Independent'),
('INDEPENDENT_LEANING_CONSERVATIVE', 'Independent leaning Republican'),
('NOT_SO_STRONG_CONSERVATIVE', 'Not so strong Republican'),
('STRONG_CONSERVATIVE', 'Strong Republican'),
('OTHER', 'Other'),
('DONT_KNOW', "Don't know"),)
democrat_republican = models.CharField(null=True, max_length=100, default=None, choices = DEMOCRAT_REPUBLICAN, verbose_name = 'What most clearly reflects your political leaning?')
VOTING_RIGHTS = (
('EXTREAMLY_IMPORTANT', 'Extremely important'),
('VERY_IMPORTANT', 'Very important'),
('MODERATELY_IMPORTANT', 'Moderately Important'),
('SOMEWHAT_IMPORTANT', 'Somewhat important'),
('NOT_VERY_IMPORTANT', 'Not very important'),
('OF_NO_IMPORTANCE', 'Of no importance'),
('OTHER', 'Other'),
('DONT_KNOW', "Don't know"),)
voting_rights = models.CharField(null=True, max_length=100, default=None, choices = VOTING_RIGHTS, verbose_name = 'How important do you feel it is to exercise your voting rights?')
ELECTION_TYPE = (
('NONE', 'None'),
('LOCAL', 'Local elections'),
('STATE', 'State elections e.g. Governorship'),
('NATIONAL', 'National elections e.g. Congress and Senate'),
('PRESIDENTIAL', 'Presidential elections'),
('OTHER', 'Other'),
('DONT_KNOW', "Don't know"),)
election = MultiSelectField(null=True, max_length=100, choices=ELECTION_TYPE, verbose_name = 'Which elections do you regularly vote in or intend to vote in? Select all that apply.')
NEWS_ACCESS = (
('RADIO', 'Radio'),
('TV', 'TV'),
('NEWSPAPERS', 'Newspaper'),
('ONLINE', 'Online'),
('NONE', 'None'),
('OTHER', 'Other'),)
news_access = MultiSelectField( max_length=100, choices=NEWS_ACCESS, verbose_name = 'Which news mediums do you access most often? Select all that apply.')
STATION_ACCESS = (
('NBC', 'NBC'),
('CBS', 'CBS'),
('ABC', 'ABC'),
('Fox', 'Fox'),
('The_CW', 'The CW'),
('PBS', 'PBS'),
('LOCAL', 'Local'),
('NONE', 'None'),
('OTHER', 'Other'),)
station_access = MultiSelectField( max_length=100, choices=STATION_ACCESS, verbose_name = 'Which TV stations do you watch on a regular basis? Select all that apply.')
# clean function which checks if 'other' boxes are selected in the survey and requires user to fill out additional information
def clean(self):
if self.party_benefit == 'YES_OTHER' and not self.party_benefit_message:
raise ValidationError({'party_benefit_message': ['Required when \"Other\" is checked']})
if self.topics == 'OTHER' and not self.topics_message:
raise ValidationError({'topics_message': ['Required when \"Other\" is checked']})
if self.deliberate == 'YES_DELIBERATE' and not self.deliberate_message:
raise ValidationError({'deliberate_message': ['Required when \"Yes\" is checked']})
if self.elements_features == 'ELEMENTS_YES' and not self.elements_features_message:
raise ValidationError({'elements_features_message': ['Required when \"Yes\" is checked']})
if self.limit_elements_features == 'LIMIT_ELEMENTS_YES' and not self.limit_elements_features_message:
raise ValidationError({'limit_elements_features_message': ['Required when \"Yes\" is checked']})
def __unicode__(self):
return self