SlideShare uma empresa Scribd logo
1 de 21
Baixar para ler offline
Two Scoops of Django
Chapter 9 Common Patterns for Forms

Alfred
Forms
This chapter goes explicitly into the
concepts of forms, models and CBVs. There
are five common patterns.
Pattern 1: Simple ModelForm
with default Validators
Pattern 1: Simple ModelForm
with default Validators

• Auto generated a model form based on the
Flavor model.
Pattern 2: Custom Form Field
Validators in ModelForm
Pattern 2: Custom Form Field
Validators in ModelForm

• Customize your validator.
Pattern 2: Custom Form Field
Validators in ModelForm(cont.)

• To use it

•what if we wanted to use validate_tasty() in just forms?	

•what if we wanted to assign it to other fields?
Pattern 2: Custom Form Field
Validators in ModelForm(cont.)

• To create a customized form...
#forms.py	
from django import forms	
from core.validators import validate_tasty	
from .models import Flavor	

!
class FlavorForm(forms.ModelForm):	
def __init__(self, *args, **kwargs):	
super(FlavorForm, self).__init__(args, kwargs)	
self.fields["title"].validators.append(validate_tasty)	
self.fields["slug"].validators.append(validate_tasty)	

!
class Meta:	
model = Flavor
Pattern 2: Custom Form Field
Validators in ModelForm(cont.)
#views.py	
from django.contrib import messages	
from django.views.generic import CreateView, UpdateView, DetailView	
from braces.views import LoginRequiredMixin	
from .models import Flavor	
from .forms import FlavorForm	

!

class FlavorActionMixin(object):	
model = Flavor	
@property	
def action(self):	
msg = "{0} is missing action.".format(self.__class__)	
raise NotImplementedError(msg)	

!
!

def form_valid(self, form):	
msg = "Flavor {0}!".format(self.action)	
messages.info(self.request, msg)	
return super(FlavorActionMixin, self).form_valid(form)	

class FlavorCreateView(LoginRequiredMixin, FlavorActionMixin, CreateView):	
model = Flavor	
action = "created"	
form_class = FlavorForm	

!

class FlavorUpdatedView(LoginRequiredMixin, FlavorActionMixin, UpdateView):	
model = Flavor	
action = "updated"	
form_class = FlavorForm	

!

class FlavorDetailView(DetailView):	
model = Flavor
Pattern 3: Overriding the clean
stage of Validation
Pattern 3: Overriding the clean
stage of Validation

• Multi-field validation	

• Validation involving existing data from the
database that has already been validated.	

clean() and clean<field_name>()	

•

clean() method is the place to validate two or more fields
against each other, since it’s not specific to any one particular
field.	


•

The clean validation stage is a better place to attach validation
against persistent data.
Pattern 3: Overriding the clean
stage of Validation(cont.)

• We are going to check the remaining amount
is enough or not...

class IceCreamOrderForm(forms.ModelForm):	
slug = forms.ChoiceField("Flavor")	
toppings = forms.CharField()	

!
!

def __init__(self, *args, **kwargs):	
super(IceCreamOrderForm, self).__init__(*args, **kwargs)	
self.fields["slug"].choices = [ (x.slug, x.title) for x in Flavor.objects.all() ]	
def clean_slug(self):	
slug = self.cleaned_data["slug"]	
if Flavor.objects.get(slug=slug).scoops_remainin <= 0:	
msg = u"sorry, we are out of flavor"	
raise forms.ValidationError(msg)	
return slug
Pattern 3: Overriding the clean
stage of Validation(cont.)

• And then check multiple fields..
class IceCreamOrderForm(forms.ModelForm):	
...	
def clean(self):	
cleaned_data = super(IceCreamOrderForm, self).clean()	
slug = cleaned_data.get("slug", "")	
toppings = cleaned_data.get("toppings", "")	
if u"chocolate" in slug.lower() and u"chocolate" in toppings.lower():	
msg = u"Your order has too much chocolate."	
raise forms.ValidationError(msg)	
return cleaned_data
Pattern 4: Hacking Form Fields
Pattern 4: Hacking Form Fields

• you have a ice cream store, some of fields
are required, some are not.

from django.db import models	
from django.core.urlresolvers import reverse	
# Create your models here.	

!
class IceCreamStore(models.Model):	
title = models.CharField(max_length=100)	
block_address = models.TextField()	
phone = models.CharField(max_length=20, blank=True)	
description = models.TextField(blank=True)	
def get_absolute_url(self):	
return reverse("store_detail", kwargs={"pk":self.pk})
Pattern 4: Hacking Form
Fields(cont.)

• Old style v.s. better style

from django import forms	
from models import IceCreamStore	
class IceCreamStoreUpdateForm(forms.ModelForm):	

!
phone = forms.CharField(required=True) #duplicate	
description = forms.TextField(required=True) #duplicate	

!
class Meta:	
model = IceCreamStore	
class IceCreamStoreUpdateForm(forms.ModelForm):	

!
!

class Meta:	
model = IceCreamStore	
def __init__(self, *args, **kwargs):	
super(IceCreamStoreUpdateForm, self).__init__(*args, **kwargs)	
self.fields["phone"].required=True	
self.fields["description"].required=True
Pattern 4: Hacking Form
Fields(cont.)

• Much Better Style
from django import forms	
from models import IceCreamStore	

!

class IceCreamStoreCreateForm(forms.ModelForm):	
class Meta:	
model = IceCreamStore	
field = ("title", "block_address", )	

!

class IceCreamStoreUpdateForm(IceCreamStoreCreateForm):	
def __init__(self, *args, **kwargs):	
super(IceCreamStoreUpdateForm, self).__init__(*args, **kwargs)	
self.fields["phone"].required=True	
self.fields["description"].required=True	

!
!

class Meta:	
model = IceCreamStore	
fields = ("title", "block_address", "phone", "description")
Pattern 4: Hacking Form
Fields(cont.)

• Use it in view
from
from
from
from

django.views.generic import CreateView, UpdateView	
forms import IceCreamStoreCreateForm	
forms import IceCreamStoreUpdateForm	
models import IceCreamStore	

!
class IceCreamCreateView(CreateView):	
model=IceCreamStore	
form_class=IceCreamStoreCreateForm	

!
class IceCreamUpdateView(UpdateView):	
model=IceCreamStore	
form_class=IceCreamStoreUpdateForm
Pattern 5: Reusable Searching
Mixin View
Pattern 5: Reusable Searching
Mixin View

• Use a simple search view on multiple models
class TitleSearchMixin(object):	
def get_queryset(self):	
queryset = super(TitleSearchMixin, self).get_queryset()	

!

!

q = self.request.GET.get("q")	
if q:	
return queryset.filter(title__icontains=q)	
return queryset	
{#form go into store#}	

class FlavorListView(TitleSearchMixin, ListView):	
model = Flavor	

!

class StoreListView(TitleSearchMixin, ListView):	
model = Store

<form action="" method="GET">	
<input type="text" name="q"/>	
<button type="submit">search</
button>	
</form>	
{#form go into flavor#}	
<form action="" method="GET">	
<input type="text" name="q"/>	
<button type="submit">search</
button>	
</form>
Thanks
Alfred

Mais conteúdo relacionado

Mais procurados

Presentation technico-commercial-ruby-on-rails
Presentation technico-commercial-ruby-on-railsPresentation technico-commercial-ruby-on-rails
Presentation technico-commercial-ruby-on-rails
Novelys
 

Mais procurados (19)

Common Pitfalls Experienced in Java
Common Pitfalls Experienced in JavaCommon Pitfalls Experienced in Java
Common Pitfalls Experienced in Java
 
Validation
ValidationValidation
Validation
 
Repensando o Desenvolvimento Web com Ruby on Rails
Repensando o Desenvolvimento Web com Ruby on RailsRepensando o Desenvolvimento Web com Ruby on Rails
Repensando o Desenvolvimento Web com Ruby on Rails
 
What's New in newforms-admin
What's New in newforms-adminWhat's New in newforms-admin
What's New in newforms-admin
 
Working With The Symfony Admin Generator
Working With The Symfony Admin GeneratorWorking With The Symfony Admin Generator
Working With The Symfony Admin Generator
 
Presentation technico-commercial-ruby-on-rails
Presentation technico-commercial-ruby-on-railsPresentation technico-commercial-ruby-on-rails
Presentation technico-commercial-ruby-on-rails
 
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
 
Specs2
Specs2Specs2
Specs2
 
Refatoração + Design Patterns em Ruby
Refatoração + Design Patterns em RubyRefatoração + Design Patterns em Ruby
Refatoração + Design Patterns em Ruby
 
Form demoinplaywithmysql
Form demoinplaywithmysqlForm demoinplaywithmysql
Form demoinplaywithmysql
 
Xml operations in odoo
Xml operations in odooXml operations in odoo
Xml operations in odoo
 
HTML Form Part 1
HTML Form Part 1HTML Form Part 1
HTML Form Part 1
 
Java Script
Java ScriptJava Script
Java Script
 
Django ORM - Marcin Markiewicz
Django ORM - Marcin Markiewicz Django ORM - Marcin Markiewicz
Django ORM - Marcin Markiewicz
 
Dig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup CairoDig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup Cairo
 
Django Forms: Best Practices, Tips, Tricks
Django Forms: Best Practices, Tips, TricksDjango Forms: Best Practices, Tips, Tricks
Django Forms: Best Practices, Tips, Tricks
 
Grain final border one
Grain final border oneGrain final border one
Grain final border one
 
Django Admin (Python meeutp)
Django Admin (Python meeutp)Django Admin (Python meeutp)
Django Admin (Python meeutp)
 
2013-06-25 - HTML5 & JavaScript Security
2013-06-25 - HTML5 & JavaScript Security2013-06-25 - HTML5 & JavaScript Security
2013-06-25 - HTML5 & JavaScript Security
 

Semelhante a Two scoopsofdjango common patterns for forms

Testing for Pragmatic People
Testing for Pragmatic PeopleTesting for Pragmatic People
Testing for Pragmatic People
davismr
 
Ctools presentation
Ctools presentationCtools presentation
Ctools presentation
Digitaria
 
Introduction To Django (Strange Loop 2011)
Introduction To Django (Strange Loop 2011)Introduction To Django (Strange Loop 2011)
Introduction To Django (Strange Loop 2011)
Jacob Kaplan-Moss
 
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalksSelenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Lohika_Odessa_TechTalks
 

Semelhante a Two scoopsofdjango common patterns for forms (20)

Django tricks (2)
Django tricks (2)Django tricks (2)
Django tricks (2)
 
Django Pro ORM
Django Pro ORMDjango Pro ORM
Django Pro ORM
 
Тестирование и Django
Тестирование и DjangoТестирование и Django
Тестирование и Django
 
Profile django
Profile djangoProfile django
Profile django
 
Testing for Pragmatic People
Testing for Pragmatic PeopleTesting for Pragmatic People
Testing for Pragmatic People
 
Mastering solr
Mastering solrMastering solr
Mastering solr
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
 
Optimization in django orm
Optimization in django ormOptimization in django orm
Optimization in django orm
 
Tango with django
Tango with djangoTango with django
Tango with django
 
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
 
Ctools presentation
Ctools presentationCtools presentation
Ctools presentation
 
Django forms
Django formsDjango forms
Django forms
 
BarcelonaJUG2016: walkmod: how to run and design code transformations
BarcelonaJUG2016: walkmod: how to run and design code transformationsBarcelonaJUG2016: walkmod: how to run and design code transformations
BarcelonaJUG2016: walkmod: how to run and design code transformations
 
An Introduction To Python - Functions, Part 1
An Introduction To Python - Functions, Part 1An Introduction To Python - Functions, Part 1
An Introduction To Python - Functions, Part 1
 
Wheels
WheelsWheels
Wheels
 
What's new in Django 1.7
What's new in Django 1.7What's new in Django 1.7
What's new in Django 1.7
 
Django Good Practices
Django Good PracticesDjango Good Practices
Django Good Practices
 
Pruebas unitarias con django
Pruebas unitarias con djangoPruebas unitarias con django
Pruebas unitarias con django
 
Introduction To Django (Strange Loop 2011)
Introduction To Django (Strange Loop 2011)Introduction To Django (Strange Loop 2011)
Introduction To Django (Strange Loop 2011)
 
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalksSelenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
 

Último

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Último (20)

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
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
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
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)
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
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
 

Two scoopsofdjango common patterns for forms

  • 1. Two Scoops of Django Chapter 9 Common Patterns for Forms Alfred
  • 2. Forms This chapter goes explicitly into the concepts of forms, models and CBVs. There are five common patterns.
  • 3. Pattern 1: Simple ModelForm with default Validators
  • 4. Pattern 1: Simple ModelForm with default Validators • Auto generated a model form based on the Flavor model.
  • 5. Pattern 2: Custom Form Field Validators in ModelForm
  • 6. Pattern 2: Custom Form Field Validators in ModelForm • Customize your validator.
  • 7. Pattern 2: Custom Form Field Validators in ModelForm(cont.) • To use it •what if we wanted to use validate_tasty() in just forms? •what if we wanted to assign it to other fields?
  • 8. Pattern 2: Custom Form Field Validators in ModelForm(cont.) • To create a customized form... #forms.py from django import forms from core.validators import validate_tasty from .models import Flavor ! class FlavorForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(FlavorForm, self).__init__(args, kwargs) self.fields["title"].validators.append(validate_tasty) self.fields["slug"].validators.append(validate_tasty) ! class Meta: model = Flavor
  • 9. Pattern 2: Custom Form Field Validators in ModelForm(cont.) #views.py from django.contrib import messages from django.views.generic import CreateView, UpdateView, DetailView from braces.views import LoginRequiredMixin from .models import Flavor from .forms import FlavorForm ! class FlavorActionMixin(object): model = Flavor @property def action(self): msg = "{0} is missing action.".format(self.__class__) raise NotImplementedError(msg) ! ! def form_valid(self, form): msg = "Flavor {0}!".format(self.action) messages.info(self.request, msg) return super(FlavorActionMixin, self).form_valid(form) class FlavorCreateView(LoginRequiredMixin, FlavorActionMixin, CreateView): model = Flavor action = "created" form_class = FlavorForm ! class FlavorUpdatedView(LoginRequiredMixin, FlavorActionMixin, UpdateView): model = Flavor action = "updated" form_class = FlavorForm ! class FlavorDetailView(DetailView): model = Flavor
  • 10. Pattern 3: Overriding the clean stage of Validation
  • 11. Pattern 3: Overriding the clean stage of Validation • Multi-field validation • Validation involving existing data from the database that has already been validated. clean() and clean<field_name>() • clean() method is the place to validate two or more fields against each other, since it’s not specific to any one particular field. • The clean validation stage is a better place to attach validation against persistent data.
  • 12. Pattern 3: Overriding the clean stage of Validation(cont.) • We are going to check the remaining amount is enough or not... class IceCreamOrderForm(forms.ModelForm): slug = forms.ChoiceField("Flavor") toppings = forms.CharField() ! ! def __init__(self, *args, **kwargs): super(IceCreamOrderForm, self).__init__(*args, **kwargs) self.fields["slug"].choices = [ (x.slug, x.title) for x in Flavor.objects.all() ] def clean_slug(self): slug = self.cleaned_data["slug"] if Flavor.objects.get(slug=slug).scoops_remainin <= 0: msg = u"sorry, we are out of flavor" raise forms.ValidationError(msg) return slug
  • 13. Pattern 3: Overriding the clean stage of Validation(cont.) • And then check multiple fields.. class IceCreamOrderForm(forms.ModelForm): ... def clean(self): cleaned_data = super(IceCreamOrderForm, self).clean() slug = cleaned_data.get("slug", "") toppings = cleaned_data.get("toppings", "") if u"chocolate" in slug.lower() and u"chocolate" in toppings.lower(): msg = u"Your order has too much chocolate." raise forms.ValidationError(msg) return cleaned_data
  • 14. Pattern 4: Hacking Form Fields
  • 15. Pattern 4: Hacking Form Fields • you have a ice cream store, some of fields are required, some are not. from django.db import models from django.core.urlresolvers import reverse # Create your models here. ! class IceCreamStore(models.Model): title = models.CharField(max_length=100) block_address = models.TextField() phone = models.CharField(max_length=20, blank=True) description = models.TextField(blank=True) def get_absolute_url(self): return reverse("store_detail", kwargs={"pk":self.pk})
  • 16. Pattern 4: Hacking Form Fields(cont.) • Old style v.s. better style from django import forms from models import IceCreamStore class IceCreamStoreUpdateForm(forms.ModelForm): ! phone = forms.CharField(required=True) #duplicate description = forms.TextField(required=True) #duplicate ! class Meta: model = IceCreamStore class IceCreamStoreUpdateForm(forms.ModelForm): ! ! class Meta: model = IceCreamStore def __init__(self, *args, **kwargs): super(IceCreamStoreUpdateForm, self).__init__(*args, **kwargs) self.fields["phone"].required=True self.fields["description"].required=True
  • 17. Pattern 4: Hacking Form Fields(cont.) • Much Better Style from django import forms from models import IceCreamStore ! class IceCreamStoreCreateForm(forms.ModelForm): class Meta: model = IceCreamStore field = ("title", "block_address", ) ! class IceCreamStoreUpdateForm(IceCreamStoreCreateForm): def __init__(self, *args, **kwargs): super(IceCreamStoreUpdateForm, self).__init__(*args, **kwargs) self.fields["phone"].required=True self.fields["description"].required=True ! ! class Meta: model = IceCreamStore fields = ("title", "block_address", "phone", "description")
  • 18. Pattern 4: Hacking Form Fields(cont.) • Use it in view from from from from django.views.generic import CreateView, UpdateView forms import IceCreamStoreCreateForm forms import IceCreamStoreUpdateForm models import IceCreamStore ! class IceCreamCreateView(CreateView): model=IceCreamStore form_class=IceCreamStoreCreateForm ! class IceCreamUpdateView(UpdateView): model=IceCreamStore form_class=IceCreamStoreUpdateForm
  • 19. Pattern 5: Reusable Searching Mixin View
  • 20. Pattern 5: Reusable Searching Mixin View • Use a simple search view on multiple models class TitleSearchMixin(object): def get_queryset(self): queryset = super(TitleSearchMixin, self).get_queryset() ! ! q = self.request.GET.get("q") if q: return queryset.filter(title__icontains=q) return queryset {#form go into store#} class FlavorListView(TitleSearchMixin, ListView): model = Flavor ! class StoreListView(TitleSearchMixin, ListView): model = Store <form action="" method="GET"> <input type="text" name="q"/> <button type="submit">search</ button> </form> {#form go into flavor#} <form action="" method="GET"> <input type="text" name="q"/> <button type="submit">search</ button> </form>