Your SlideShare is downloading. ×
0
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Two scoopsofdjango   common patterns for forms
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Two scoopsofdjango common patterns for forms

801

Published on

Published in: Technology, Business
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
801
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
12
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 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>
  • 21. Thanks Alfred

×