SlideShare una empresa de Scribd logo
1 de 26
Descargar para leer sin conexión
Forms, Getting Your
  Money's Worth
     Alex Gaynor
What Are Forms For?
•They are a way to get data from the
user
django.forms
•Encapsulate forms into objects
•Know how to validate our data
•In the case of ModelForms, they
know how to save data
•Formsets: Multiple of the same
type of Form
•Understand part of the idea of the
HTTP request/response cycle
The 20 second recap
from django import forms

from myapp.models import MyModel

class MyForm(forms.Form):
    my_field = forms.CharField()
    other_field = forms.BooleanField(widget=forms.Select)

class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
Going beyond the basics
•What you just saw is how 90% of
people use django.forms
•That's using classes to define static
forms that don't change
•But that's not how most
applications are
•What are some common tasks that
aren't static, or otherwise handled
by this setup?
Problems to Solve
•Multiple forms of different types
•Altering a form's options
dynamically
•Building entire forms dynamically
Multiple Forms
  •Formsets let us handle multiple
  forms of one type, for example
  letting a user enter multiple books
  •We can manually pass around
  multiple forms
user_form = UserForm()
profile_form = UserProfileForm()
return render_to_response({
    'user_form': user_form,
    'profile_form': profile_form,
})
Doing a bit Better
•That's really ugly, doesn't scale well
•What would be easier?
•One class to hold all of our forms
•It should act like it's just a normal
form object where possible
•How do we build this?
•Normal python tools of the trade,
dynamically creating classes
def multipleform_factory(form_classes,
    form_order=None):


    if form_order:
        form_classes = SortedDict([
            (prefix, form_classes[prefix])
            for prefix in form_order])
    else:
        form_classes =
SortedDict(form_classes)
    return type('MultipleForm',
        (MultipleFormBase,),
        {'form_classes': form_classes})
How type() works
type(object) -> returns the class of the object,
type(1) == int
type([]) == list


type(name, bases, attrs) -> returns a new class named
  {{ name }}, inherits from {{ bases}}, and has attributes of
  {{ attrs}}


class MyForm(forms.Form):
  my_field = forms.CharField()


type('MyForm', (forms.Form,),
  {'my_field': forms.CharField()}
class MutlipleFormBase(object):
    def __init__(self, data, files):
        self.forms = [form_class(data, files,
prefix=prefix) for form_class, prefix in
self.form_classes.iteritems()]


    def as_table(self):
        return 'n'.join([form.as_table() for
form in self.forms])


    def save(self, commit=True):
        return tuple([form.save(commit) for
form in self.forms])

     def is_valid(self):
         return all(form.is_valid() for form
in
How it works
•Simple factory function creates a
new class that subclasses
MultipleFormBase, gives it an extra
attribute, a dict of form classes
•MultipleFormBase just emulates
the API of Form and ModelForm,
aggregating the methods as
appropriate
class UserForm(forms.ModelForm):
    class Meta:
        model = User


class ProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile


UserProfileForm = multipleform_factory({
    'user': UserForm,
    'profile': ProfileForm,
}, ['user', 'profile'])
The Result
•Now we can use UserProfileForm
the same way we would a regular
form.
•We need to expand
MultipleFormBase to implement
the rest of the Form API, but these
additional methods are trivial.
A More Dynamic Form
•Not all users should see the same
form
•Simple example: a user should only
be able to select an option from a
dropdown if it belongs to them
•Tools of the trade: Subclassing
methods
class ObjectForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        super(ObjectForm,
            self).__init__(*args, **kwargs)
        self.fields['related'].queryset = 

self.fields['related'].queryset. 
            filter(owner=user)
    class Meta:
        model = Object
Dead Simple
•Now when we instantiate our form
we just need to prive a user kwarg.
•Form and ModelForm are just
python. We overide methods to add
our own behavior, then call super().
•We can apply this same technique
anywhere in Python, to any method.
Building it Dynamically
•What if we don't just want to alter
our form per request, what if we
want to build the whole thing
dynamically?
•Common example: a survey
application where we keep the
survey questions in the database.
•Let's build it.
The Pieces
•What do we need to build this
survey application?
•A Model for a Survey and another
for Fields on each Form(we're
keeping it simple).
•A function to take a Survey object
and turn it into a Form subclass.
class Survey(models.Model):
    name = models.CharField(max_length=100)


FIELD_TYPE_CHOICES = (
    (0, 'charfield'),
    (1, 'textfield'),
    (2, 'boolean'),
)


class Question(models.Model):
    survey = models.ForeignKey(Survey,
        related_name='questions')
    label = models.CharField(max_length=255)
    field_type = models.IntegerField(choices=
        FIELD_TYPE_CHOICES)
FIELD_TYPES = {
    0: forms.CharField,
    1: curry(forms.CharField,
        widget=forms.Textarea)
    2: forms.BooleanField
}


def form_form_survey(survey):
    fields = {}
    for question in survey.questions.all():
        fields[question.label] =
            FIELD_TYPES[question.field_type](
                label = question.label
            )
    return type('%sForm' % survey.name,
        (forms.Form,), fields)
What do We Have
•2 very simple models for storing
our surveys and the questions for
these surveys
•a way to create actual forms.Form
classes for a survey
•now we can use these forms in our
views the same as normal
What Don't We have
•Handling for more complex field
types(such as choices)
•A way to create Surveys(other than
the admin, which would actually
work really well for this)
•A way to save the results of a
survey
•Consider these an excersise for the
reader
Recap
•Use standard Python to extend
what we have
•Don't be afraid to build your own
things on top of what we already
have
•It's just Python
Questions?

P.S.: If you're someone who needs
multiple datbase support in Django
           come talk to me

Más contenido relacionado

La actualidad más candente

Jquery presentation
Jquery presentationJquery presentation
Jquery presentation
guest5d87aa6
 
OpenERP Technical Memento
OpenERP Technical MementoOpenERP Technical Memento
OpenERP Technical Memento
Odoo
 
Zend_Form to the Rescue - A Brief Introduction to Zend_Form
Zend_Form to the Rescue - A Brief Introduction to Zend_FormZend_Form to the Rescue - A Brief Introduction to Zend_Form
Zend_Form to the Rescue - A Brief Introduction to Zend_Form
Jeremy Kendall
 
Two scoopsofdjango common patterns for forms
Two scoopsofdjango   common patterns for formsTwo scoopsofdjango   common patterns for forms
Two scoopsofdjango common patterns for forms
Shih-yi Wei
 
Action View Form Helpers - 2, Season 2
Action View Form Helpers - 2, Season 2Action View Form Helpers - 2, Season 2
Action View Form Helpers - 2, Season 2
RORLAB
 
CSS: selectors and the box model
CSS: selectors and the box modelCSS: selectors and the box model
CSS: selectors and the box model
Idan Gazit
 

La actualidad más candente (14)

Powerful Generic Patterns With Django
Powerful Generic Patterns With DjangoPowerful Generic Patterns With Django
Powerful Generic Patterns With Django
 
Jquery presentation
Jquery presentationJquery presentation
Jquery presentation
 
Jsf lab
Jsf labJsf lab
Jsf lab
 
Form Validation in JavaScript
Form Validation in JavaScriptForm Validation in JavaScript
Form Validation in JavaScript
 
OpenERP Technical Memento
OpenERP Technical MementoOpenERP Technical Memento
OpenERP Technical Memento
 
Rapid Prototyping with PEAR
Rapid Prototyping with PEARRapid Prototyping with PEAR
Rapid Prototyping with PEAR
 
Tutorial_4_PHP
Tutorial_4_PHPTutorial_4_PHP
Tutorial_4_PHP
 
Symfony 2
Symfony 2Symfony 2
Symfony 2
 
Zend_Form to the Rescue - A Brief Introduction to Zend_Form
Zend_Form to the Rescue - A Brief Introduction to Zend_FormZend_Form to the Rescue - A Brief Introduction to Zend_Form
Zend_Form to the Rescue - A Brief Introduction to Zend_Form
 
Two scoopsofdjango ch16 dealing with the user model
Two scoopsofdjango ch16   dealing with the user modelTwo scoopsofdjango ch16   dealing with the user model
Two scoopsofdjango ch16 dealing with the user model
 
Two scoopsofdjango common patterns for forms
Two scoopsofdjango   common patterns for formsTwo scoopsofdjango   common patterns for forms
Two scoopsofdjango common patterns for forms
 
Action View Form Helpers - 2, Season 2
Action View Form Helpers - 2, Season 2Action View Form Helpers - 2, Season 2
Action View Form Helpers - 2, Season 2
 
The Django Book, Chapter 16: django.contrib
The Django Book, Chapter 16: django.contribThe Django Book, Chapter 16: django.contrib
The Django Book, Chapter 16: django.contrib
 
CSS: selectors and the box model
CSS: selectors and the box modelCSS: selectors and the box model
CSS: selectors and the box model
 

Destacado

steps in Questionnaire design
steps in Questionnaire designsteps in Questionnaire design
steps in Questionnaire design
heena pathan
 
Grammar - Articles - a, an, or the
Grammar - Articles - a, an, or theGrammar - Articles - a, an, or the
Grammar - Articles - a, an, or the
Evan Brammer
 

Destacado (15)

Advanced Django Forms Usage
Advanced Django Forms UsageAdvanced Django Forms Usage
Advanced Django Forms Usage
 
Fotoboek Rouwwerk
Fotoboek RouwwerkFotoboek Rouwwerk
Fotoboek Rouwwerk
 
THE SURVEY OCTOPUS: GETTING VALID DATA FROM SURVEYS
THE SURVEY OCTOPUS: GETTING VALID DATA FROM SURVEYSTHE SURVEY OCTOPUS: GETTING VALID DATA FROM SURVEYS
THE SURVEY OCTOPUS: GETTING VALID DATA FROM SURVEYS
 
Questionnaires (Research)
Questionnaires (Research)Questionnaires (Research)
Questionnaires (Research)
 
The Survey Octopus - getting valid data from surveys, presentation for UX in ...
The Survey Octopus - getting valid data from surveys, presentation for UX in ...The Survey Octopus - getting valid data from surveys, presentation for UX in ...
The Survey Octopus - getting valid data from surveys, presentation for UX in ...
 
How to Write a Popular Python Library by Accident
How to Write a Popular Python Library by AccidentHow to Write a Popular Python Library by Accident
How to Write a Popular Python Library by Accident
 
Questionnaires and surveys
Questionnaires and surveysQuestionnaires and surveys
Questionnaires and surveys
 
The Art of Asking Survey Questions: 7 Survey-Writing Don'ts
The Art of Asking Survey Questions: 7 Survey-Writing Don'tsThe Art of Asking Survey Questions: 7 Survey-Writing Don'ts
The Art of Asking Survey Questions: 7 Survey-Writing Don'ts
 
Definite and Indefinite Articles
Definite and Indefinite ArticlesDefinite and Indefinite Articles
Definite and Indefinite Articles
 
Ppt on article by manish kumar
Ppt on article by manish kumarPpt on article by manish kumar
Ppt on article by manish kumar
 
Questionnaire Design
Questionnaire DesignQuestionnaire Design
Questionnaire Design
 
Grammar articles
Grammar articlesGrammar articles
Grammar articles
 
steps in Questionnaire design
steps in Questionnaire designsteps in Questionnaire design
steps in Questionnaire design
 
A an-the ppt.
A an-the ppt.A an-the ppt.
A an-the ppt.
 
Grammar - Articles - a, an, or the
Grammar - Articles - a, an, or theGrammar - Articles - a, an, or the
Grammar - Articles - a, an, or the
 

Similar a Forms, Getting Your Money's Worth

What’S New In Newforms Admin
What’S New In Newforms AdminWhat’S New In Newforms Admin
What’S New In Newforms Admin
DjangoCon2008
 
Symfony2 Introduction Presentation
Symfony2 Introduction PresentationSymfony2 Introduction Presentation
Symfony2 Introduction Presentation
Nerd Tzanetopoulos
 
...and thus your forms automagically disappeared
...and thus your forms automagically disappeared...and thus your forms automagically disappeared
...and thus your forms automagically disappeared
Luc Bors
 
Odoo (open erp) creating a module
Odoo (open erp) creating a moduleOdoo (open erp) creating a module
Odoo (open erp) creating a module
Tarun Behal
 
Task 2
Task 2Task 2
Task 2
EdiPHP
 

Similar a Forms, Getting Your Money's Worth (20)

What’S New In Newforms Admin
What’S New In Newforms AdminWhat’S New In Newforms Admin
What’S New In Newforms Admin
 
Django Admin: Widgetry & Witchery
Django Admin: Widgetry & WitcheryDjango Admin: Widgetry & Witchery
Django Admin: Widgetry & Witchery
 
Working With The Symfony Admin Generator
Working With The Symfony Admin GeneratorWorking With The Symfony Admin Generator
Working With The Symfony Admin Generator
 
Symfony2 Introduction Presentation
Symfony2 Introduction PresentationSymfony2 Introduction Presentation
Symfony2 Introduction Presentation
 
Curso Symfony - Clase 3
Curso Symfony - Clase 3Curso Symfony - Clase 3
Curso Symfony - Clase 3
 
Practical Predictive Modeling in Python
Practical Predictive Modeling in PythonPractical Predictive Modeling in Python
Practical Predictive Modeling in Python
 
Oops concepts in php
Oops concepts in phpOops concepts in php
Oops concepts in php
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
...and thus your forms automagically disappeared
...and thus your forms automagically disappeared...and thus your forms automagically disappeared
...and thus your forms automagically disappeared
 
Curso Symfony - Clase 4
Curso Symfony - Clase 4Curso Symfony - Clase 4
Curso Symfony - Clase 4
 
Django tutorial
Django tutorialDjango tutorial
Django tutorial
 
Custom Forms and Configuration Forms in Drupal 8
Custom Forms and Configuration Forms in Drupal 8Custom Forms and Configuration Forms in Drupal 8
Custom Forms and Configuration Forms in Drupal 8
 
Ruby on rails
Ruby on rails Ruby on rails
Ruby on rails
 
Lo nuevo de Django 1.7 y 1.8
Lo nuevo de Django 1.7 y 1.8Lo nuevo de Django 1.7 y 1.8
Lo nuevo de Django 1.7 y 1.8
 
Reviewing OOP Design patterns
Reviewing OOP Design patternsReviewing OOP Design patterns
Reviewing OOP Design patterns
 
Odoo (open erp) creating a module
Odoo (open erp) creating a moduleOdoo (open erp) creating a module
Odoo (open erp) creating a module
 
SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features Summary
 
Comilla University
Comilla University Comilla University
Comilla University
 
Task 2
Task 2Task 2
Task 2
 
MDE in Practice
MDE in PracticeMDE in Practice
MDE in Practice
 

Último

Último (20)

Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 

Forms, Getting Your Money's Worth

  • 1. Forms, Getting Your Money's Worth Alex Gaynor
  • 2. What Are Forms For? •They are a way to get data from the user
  • 3. django.forms •Encapsulate forms into objects •Know how to validate our data •In the case of ModelForms, they know how to save data •Formsets: Multiple of the same type of Form •Understand part of the idea of the HTTP request/response cycle
  • 4. The 20 second recap from django import forms from myapp.models import MyModel class MyForm(forms.Form): my_field = forms.CharField() other_field = forms.BooleanField(widget=forms.Select) class MyModelForm(forms.ModelForm): class Meta: model = MyModel
  • 5. Going beyond the basics •What you just saw is how 90% of people use django.forms •That's using classes to define static forms that don't change •But that's not how most applications are •What are some common tasks that aren't static, or otherwise handled by this setup?
  • 6. Problems to Solve •Multiple forms of different types •Altering a form's options dynamically •Building entire forms dynamically
  • 7. Multiple Forms •Formsets let us handle multiple forms of one type, for example letting a user enter multiple books •We can manually pass around multiple forms user_form = UserForm() profile_form = UserProfileForm() return render_to_response({ 'user_form': user_form, 'profile_form': profile_form, })
  • 8.
  • 9. Doing a bit Better •That's really ugly, doesn't scale well •What would be easier? •One class to hold all of our forms •It should act like it's just a normal form object where possible •How do we build this? •Normal python tools of the trade, dynamically creating classes
  • 10. def multipleform_factory(form_classes, form_order=None): if form_order: form_classes = SortedDict([ (prefix, form_classes[prefix]) for prefix in form_order]) else: form_classes = SortedDict(form_classes) return type('MultipleForm', (MultipleFormBase,), {'form_classes': form_classes})
  • 11. How type() works type(object) -> returns the class of the object, type(1) == int type([]) == list type(name, bases, attrs) -> returns a new class named {{ name }}, inherits from {{ bases}}, and has attributes of {{ attrs}} class MyForm(forms.Form): my_field = forms.CharField() type('MyForm', (forms.Form,), {'my_field': forms.CharField()}
  • 12. class MutlipleFormBase(object): def __init__(self, data, files): self.forms = [form_class(data, files, prefix=prefix) for form_class, prefix in self.form_classes.iteritems()] def as_table(self): return 'n'.join([form.as_table() for form in self.forms]) def save(self, commit=True): return tuple([form.save(commit) for form in self.forms]) def is_valid(self): return all(form.is_valid() for form in
  • 13. How it works •Simple factory function creates a new class that subclasses MultipleFormBase, gives it an extra attribute, a dict of form classes •MultipleFormBase just emulates the API of Form and ModelForm, aggregating the methods as appropriate
  • 14. class UserForm(forms.ModelForm): class Meta: model = User class ProfileForm(forms.ModelForm): class Meta: model = UserProfile UserProfileForm = multipleform_factory({ 'user': UserForm, 'profile': ProfileForm, }, ['user', 'profile'])
  • 15. The Result •Now we can use UserProfileForm the same way we would a regular form. •We need to expand MultipleFormBase to implement the rest of the Form API, but these additional methods are trivial.
  • 16. A More Dynamic Form •Not all users should see the same form •Simple example: a user should only be able to select an option from a dropdown if it belongs to them •Tools of the trade: Subclassing methods
  • 17. class ObjectForm(forms.ModelForm): def __init__(self, *args, **kwargs): user = kwargs.pop('user', None) super(ObjectForm, self).__init__(*args, **kwargs) self.fields['related'].queryset = self.fields['related'].queryset. filter(owner=user) class Meta: model = Object
  • 18. Dead Simple •Now when we instantiate our form we just need to prive a user kwarg. •Form and ModelForm are just python. We overide methods to add our own behavior, then call super(). •We can apply this same technique anywhere in Python, to any method.
  • 19. Building it Dynamically •What if we don't just want to alter our form per request, what if we want to build the whole thing dynamically? •Common example: a survey application where we keep the survey questions in the database. •Let's build it.
  • 20. The Pieces •What do we need to build this survey application? •A Model for a Survey and another for Fields on each Form(we're keeping it simple). •A function to take a Survey object and turn it into a Form subclass.
  • 21. class Survey(models.Model): name = models.CharField(max_length=100) FIELD_TYPE_CHOICES = ( (0, 'charfield'), (1, 'textfield'), (2, 'boolean'), ) class Question(models.Model): survey = models.ForeignKey(Survey, related_name='questions') label = models.CharField(max_length=255) field_type = models.IntegerField(choices= FIELD_TYPE_CHOICES)
  • 22. FIELD_TYPES = { 0: forms.CharField, 1: curry(forms.CharField, widget=forms.Textarea) 2: forms.BooleanField } def form_form_survey(survey): fields = {} for question in survey.questions.all(): fields[question.label] = FIELD_TYPES[question.field_type]( label = question.label ) return type('%sForm' % survey.name, (forms.Form,), fields)
  • 23. What do We Have •2 very simple models for storing our surveys and the questions for these surveys •a way to create actual forms.Form classes for a survey •now we can use these forms in our views the same as normal
  • 24. What Don't We have •Handling for more complex field types(such as choices) •A way to create Surveys(other than the admin, which would actually work really well for this) •A way to save the results of a survey •Consider these an excersise for the reader
  • 25. Recap •Use standard Python to extend what we have •Don't be afraid to build your own things on top of what we already have •It's just Python
  • 26. Questions? P.S.: If you're someone who needs multiple datbase support in Django come talk to me