SlideShare a Scribd company logo
1 of 26
Download to read offline
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

More Related Content

What's hot

Powerful Generic Patterns With Django
Powerful Generic Patterns With DjangoPowerful Generic Patterns With Django
Powerful Generic Patterns With DjangoEric Satterwhite
 
Jquery presentation
Jquery presentationJquery presentation
Jquery presentationguest5d87aa6
 
Form Validation in JavaScript
Form Validation in JavaScriptForm Validation in JavaScript
Form Validation in JavaScriptRavi Bhadauria
 
OpenERP Technical Memento
OpenERP Technical MementoOpenERP Technical Memento
OpenERP Technical MementoOdoo
 
Rapid Prototyping with PEAR
Rapid Prototyping with PEARRapid Prototyping with PEAR
Rapid Prototyping with PEARMarkus Wolff
 
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_FormJeremy Kendall
 
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 modelShih-yi Wei
 
Two scoopsofdjango common patterns for forms
Two scoopsofdjango   common patterns for formsTwo scoopsofdjango   common patterns for forms
Two scoopsofdjango common patterns for formsShih-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 2RORLAB
 
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.contribTzu-ping Chung
 
CSS: selectors and the box model
CSS: selectors and the box modelCSS: selectors and the box model
CSS: selectors and the box modelIdan Gazit
 

What's hot (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
 

Viewers also liked

Advanced Django Forms Usage
Advanced Django Forms UsageAdvanced Django Forms Usage
Advanced Django Forms UsageDaniel Greenfeld
 
Fotoboek Rouwwerk
Fotoboek RouwwerkFotoboek Rouwwerk
Fotoboek RouwwerkWendy Roos
 
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 SURVEYSUX New Zealand 2015
 
Questionnaires (Research)
Questionnaires (Research)Questionnaires (Research)
Questionnaires (Research)anitahasani123
 
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 ...Caroline Jarrett
 
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 AccidentDaniel Greenfeld
 
Questionnaires and surveys
Questionnaires and surveysQuestionnaires and surveys
Questionnaires and surveysMary Jane T.
 
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'tsHubSpot
 
Definite and Indefinite Articles
Definite and Indefinite ArticlesDefinite and Indefinite Articles
Definite and Indefinite ArticlesCintia Mota
 
Ppt on article by manish kumar
Ppt on article by manish kumarPpt on article by manish kumar
Ppt on article by manish kumarmanish kumar
 
Questionnaire Design
Questionnaire DesignQuestionnaire Design
Questionnaire Designjravish
 
steps in Questionnaire design
steps in Questionnaire designsteps in Questionnaire design
steps in Questionnaire designheena pathan
 
Grammar - Articles - a, an, or the
Grammar - Articles - a, an, or theGrammar - Articles - a, an, or the
Grammar - Articles - a, an, or theEvan Brammer
 

Viewers also liked (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 to 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 AdminDjangoCon2008
 
Django Admin: Widgetry & Witchery
Django Admin: Widgetry & WitcheryDjango Admin: Widgetry & Witchery
Django Admin: Widgetry & WitcheryPamela Fox
 
Working With The Symfony Admin Generator
Working With The Symfony Admin GeneratorWorking With The Symfony Admin Generator
Working With The Symfony Admin GeneratorJohn Cleveley
 
Symfony2 Introduction Presentation
Symfony2 Introduction PresentationSymfony2 Introduction Presentation
Symfony2 Introduction PresentationNerd Tzanetopoulos
 
Curso Symfony - Clase 3
Curso Symfony - Clase 3Curso Symfony - Clase 3
Curso Symfony - Clase 3Javier Eguiluz
 
Practical Predictive Modeling in Python
Practical Predictive Modeling in PythonPractical Predictive Modeling in Python
Practical Predictive Modeling in PythonRobert Dempsey
 
Oops concepts in php
Oops concepts in phpOops concepts in php
Oops concepts in phpCPD INDIA
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to DjangoJoaquim Rocha
 
...and thus your forms automagically disappeared
...and thus your forms automagically disappeared...and thus your forms automagically disappeared
...and thus your forms automagically disappearedLuc Bors
 
Curso Symfony - Clase 4
Curso Symfony - Clase 4Curso Symfony - Clase 4
Curso Symfony - Clase 4Javier Eguiluz
 
Django tutorial
Django tutorialDjango tutorial
Django tutorialKsd Che
 
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 8Italo Mairo
 
Ruby on rails
Ruby on rails Ruby on rails
Ruby on rails Mohit Jain
 
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.8pedroburonv
 
Reviewing OOP Design patterns
Reviewing OOP Design patternsReviewing OOP Design patterns
Reviewing OOP Design patternsOlivier Bacs
 
Odoo (open erp) creating a module
Odoo (open erp) creating a moduleOdoo (open erp) creating a module
Odoo (open erp) creating a moduleTarun Behal
 
SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummaryAmal Khailtash
 
Task 2
Task 2Task 2
Task 2EdiPHP
 

Similar to 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
 

Recently uploaded

APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 

Recently uploaded (20)

APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 

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