TIL#130 Django Form
Django Form検証
張兄札はパイソンコーナーの有効性を検査するのに最適なツールです.
これは、他のプロジェクトからCSVファイルを取得し、モデルに更新する長期アプリケーションがあると仮定したコードです.
# 나쁜 예
import csv
import StringIO
from .models import Purchase
def add_csv_purchase(rows):
rows = StringIO.StringIO(rows)
records_added = 0
for row in csv.DictReader(rows, delimiter=","):
purchase.objects.create(**row)
records_added += 1
return records_added
上のコードは検証されていません.add_csv_purchases()
関数に検証コードを追加することもできますが、そうすると、データが変更されるたびに検証コードの変更と管理が必要になります.この場合、入力データをドラムのフォームで有効性チェックします.
import csv
import StringIO
from django import forms
from .models import Pusrchase, Seller
class PurchaseForm(forms.ModelForm):
class Meta:
model = Purchase
def clean_seller(self):
seller = self.cleaned_data['seller']
try:
Seller.objects.get(name=seller)
except Seller.DoesNotExist:
msg = "{0} does not exist in purchase #{1}.".format(
seller,
self.cleaned_data['purchase_number']
)
raise forms.ValidationError(msg)
return seller
def add_csv_purchase(rows):
rows = StringIO.StringIO(rows)
records_added = 0
errors = []
for row in csv.DictReader(rows, delimiter=","):
form = PurchaseForm(row)
if form.is_valid():
form.save()
records_added += 1
else:
errors.append(form.errors)
return records_added, errors
CSRFセキュリティ
この文書には,サイト間の偽造要求を防止するために,サイト間で偽造保護(CSRF)を要求するものが内蔵されている.使い勝手が良く、開発段階で忘れてしまうと、紹介情報も見せてくれます.
CSRFセキュリティを一時的にオフにすると、マシン間でAPIサイトを作成するときです.これらの処理は、django-tastypieやdjango-rest-frameworkのようなAPIフレームワークで自動的に実行されます.
AJAXデータの追加
AJAXを使用してデータを追加する場合は、本明細書のCSRFセキュリティを使用する必要があります.逆に、AJAXでデータを送信する場合は、HTTPヘッダにX-CSRFTokenを設定します.
Formインスタンス属性の追加
フォームのメソッドには、フォームインスタンスのプロパティも必要になる場合があります.次にuserというインスタンス属性を追加するコードを示します.
# forms.py
from django import forms
from .models import Taster
class TasterForm(forms.ModelForm):
class Meta:
model = Taster
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
super(TasterForm, self).__init__(*args, **kwargs)
# views.py
from django.views.generic import UpdateView
from braces.views import LoginRequireMixin
from .forms import TasterForm
from .models import Taster
class TasterUpdateView(LoginRequireMixin, UpdateView):
model = Taster
form_class = TasterForm
success_url = "/someplace/"
def get_form_kwargs(self):
kwargs = super(TasterUpdateView, self).get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
フォームの検証方法
form.is valid()を呼び出すと
モデル・フォーム・データは、フォームに保存され、モデル・インスタンスに保存されます。
form.save()メソッドが適用されるまでモデルインスタンスとして保存されないため、この分離プロセス自体を利用することができる.
たとえば、フォーム入力の試行に失敗した詳細をさらに理解する必要がある場合は、ユーザーが入力したフォームのデータとモデルインスタンスの変更を同時に保存できます.
# models.py
from django.db import models
class ModelFormFailureHistory(models.Model):
form_data = models.TextField()
model_data = models.TextField()
# views.py
import json
from django.contrib import messages
from django.core import serializers
from core.models import ModelFormFailureHistory
class FlavorActionMixin(object):
@property
def success_msg(self):
return NotImplemented
def form_valid(self, form):
messages.info(self.request, self.success_msg)
return super(FlavorActionMixin, self).form_valid(form)
def form_invalid(self, form):
form_data = json.dumps(form.cleaned_data)
model_data = serializers.serialize("json", [form.instance])[1:-1]
ModelFormFailureHistory.objects.create(
form_data=form_data,
model_data=model_data
)
return super(FlavorActionMixin, self).form_invalid(form)
Form.add_error()
from django import forms
class IceCreamReviewForm(forms.Form):
...
def clean(self):
cleaned_data = super(TasterForm, self).clean()
flavor = cleaned_data.get('flavor')
age = cleaned_data.get('age')
if flavor == 'coffee' and age < 3:
msg = u'Coffee Ice Cream is not for Babies.'
self.add_error('flavor', msg)
self.add_error('age', msg)
return cleaned_data
Reference
この問題について(TIL#130 Django Form), 我々は、より多くの情報をここで見つけました https://velog.io/@dnpxm387/TIL-Django-Formテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol