Формаҳо ва блог бо шарҳҳо
Чаро формаҳо лозиманд
Маълумоти браузер ҳамеша аз берун меояд: корбар метавонад майдони ҳатмиро холӣ гузорад, ба ҷойи адад ҳарф нависад ё бе кушодани саҳифаи сайт дархост фиристад. Маҳдудиятҳои HTML ба интерфейс ёрӣ медиҳанд, вале сервер бояд маълумотро худаш санҷад. Формаи Django қоидаҳо, табдили навъҳо ва паёмҳои хаторо дар як синф ҷамъ мекунад.
Майдони форма қимати қабулшаванда ва виджет тарзи намоиши онро дар HTML тавсиф мекунад. Масалан, Textarea намуди майдонро дигар мекунад, вале дарозии камтаринро муайян намекунад. Формаи пайвастшуда барои санҷиш маълумот гирифтааст; формаи бемаълумот одатан барои намоиши аввали саҳифа лозим аст.
Маҳдудиятҳо ва қиматҳои покшуда
Мисолҳои зерро пайдарпай дар як файли нав иҷро кунед. Аз формаи фармоиши боздиди осорхона оғоз мекунем: ном, шумораи билетҳо ва почтаи ихтиёрӣ. IntegerField сатрро ба адад табдил медиҳад; CharField бо нобаёнӣ фосилаҳои канориро мебардорад. Майдонҳо ҳатмианд, то вақте ки required=False таъин нашавад.
is_valid() санҷишро оғоз карда, қимати мантиқӣ медиҳад. Баъди он cleaned_data қиматҳои бомуваффақият санҷидашудаи навъи дуруст ва errors хатоҳои майдонҳоро нигоҳ медорад. Ҳатто дар формаи нодуруст баъзе майдонҳо метавонанд дуруст бошанд; барои сабт ба ҳар ҳол дурустии тамоми форма лозим аст.
import django
from django.conf import settings
settings.configure(
USE_I18N=False, INSTALLED_APPS=[],
DATABASES={"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}},
)
django.setup()
from django import forms
class BookingForm(forms.Form):
name = forms.CharField(max_length=30)
tickets = forms.IntegerField(min_value=1, max_value=6)
email = forms.EmailField(required=False)
form = BookingForm({"name": " Ada ", "tickets": "2", "email": ""})
print(form.is_valid())
print(form.cleaned_data)
print(type(form.cleaned_data["tickets"]).__name__)
Натиҷа:
True
{'name': 'Ada', 'tickets': 2, 'email': ''}
int
Хатоҳо ва формаи пайвастшуда
Калиди мавҷуднабуда ва сатри холӣ бо қоидаҳои майдон санҷида мешаванд. Аввал номҳои майдонҳои хато ва баъд паёмҳои мушаххасро дидан муфид аст. errors.as_data() объектҳои ValidationError медиҳад, ки рамзи устувор доранд, масалан min_value.
BookingForm() аз BookingForm({}) фарқ мекунад: якум ба маълумот пайваст нест, дуюм маҷмӯи холӣ гирифта, майдонҳои ҳатмиро месанҷад. Санҷиш ба пойгоҳ чизе сабт намекунад: ин амали ҷудост.
bad = BookingForm({"name": " ", "tickets": "0", "email": "bad"})
print(bad.is_valid())
print(sorted(bad.errors))
print(bad.errors.as_data()["tickets"][0].code)
print(BookingForm().is_bound, BookingForm({}).is_bound)
Натиҷа:
False
['email', 'name', 'tickets']
min_value
False True
Қоидаи худӣ
Методи clean_<номи майдон> баъди табдилдиҳӣ ва санҷишҳои дохилии ҳамин майдон даъват мешавад. Он қиматро аз self.cleaned_data гирифта, бояд қимати ниҳоиро баргардонад. raise forms.ValidationError(...) хаторо ба майдон мепайвандад. Методи умумии clean() барои вобастагии байни ду майдон мувофиқ аст; хатои умумӣ ба non_field_errors() меафтад.
Дар мисол танҳо шумораи ҷуфти билетҳоро иҷозат медиҳем. Ададро баъди IntegerField месанҷем, бинобар ин бақияи тақсим бе int(...)-и дастӣ кор мекунад.
class PairBookingForm(BookingForm):
def clean_tickets(self):
tickets = self.cleaned_data["tickets"]
if tickets % 2:
raise forms.ValidationError("Маблағи ҷуфт лозим аст", code="odd")
return tickets
for tickets in ["2", "3"]:
form = PairBookingForm({"name": "Ada", "tickets": tickets})
print(form.is_valid())
if form.errors:
print(form.errors["tickets"][0])
Натиҷа:
True
False
Маблағи ҷуфт лозим аст
ModelForm ва сабт
ModelForm майдонҳоро аз модел месозад. Дар Meta.fields танҳо майдонҳоеро номбар мекунанд, ки корбар ҳаққи таҳрирашонро дорад. save() баъди санҷиши муваффақ сабт месозад; бо instance=объект сабти мавҷударо нав мекунад. save(commit=False) намунаи ҳанӯз сабтнашударо медиҳад: қиматҳои хизматиро илова карда, save()-и онро алоҳида даъват кардан мумкин аст.
Дар зер модели хурди фармоиш аст. Калид ва шумораи сабтҳо нишон медиҳанд, ки объекти нав воқеан ба пойгоҳ даромад, на ин ки танҳо луғат санҷида шуд.
from django.db import models, connection
class Booking(models.Model):
name = models.CharField(max_length=30)
tickets = models.PositiveIntegerField()
class Meta:
app_label = "learn"
with connection.schema_editor() as editor:
editor.create_model(Booking)
class BookingModelForm(forms.ModelForm):
class Meta:
model = Booking
fields = ["name", "tickets"]
form = BookingModelForm({"name": " Lin ", "tickets": "4"})
print(form.is_valid())
obj = form.save(commit=False)
print(obj.pk)
obj.save()
print(obj.pk, obj.name, obj.tickets, Booking.objects.count())
Натиҷа:
True
None
1 Lin 4 1
Маълумот чӣ гуна санҷида мешавад
Форма ба қабулгоҳ монанд аст: аввал мавҷудияти ҳуҷҷатҳоро месанҷанд ва ба шакли лозимӣ меоранд, баъд қоидаҳои ҳар майдонро татбиқ мекунанд, сипас майдонҳоро байни ҳам муқоиса мекунанд. Барои ҳар майдон табдили навъ, санҷишҳо ва clean_<майдон> иҷро мешаванд. Баъди он clean()-и умумӣ даъват мешавад. Дар ModelForm санҷишҳои модел ва ягонагӣ ҳам илова мешаванд.
Дар view одатан GET ва POST-ро ҷудо мекунанд: дар GET формаи бемаълумотро нишон медиҳанд, дар POST request.POST-ро дода, is_valid()-ро даъват мекунанд ва танҳо қиматҳои покшударо сабт мекунанд. Баъди муваффақият redirect истифода мешавад: браузер GET-и нав иҷро мекунад. Ин нақшаи Post/Redirect/Get такрори фиристодани одиро ҳангоми навсозии саҳифа пешгирӣ мекунад.
redirect метавонад номи масир ва аргументҳои онро гирад. Барои формаи нодуруст мувофиқи шартномаи барнома ҳамон саҳифаро бо хатоҳо ё ҷавоби 400 баргардондан мумкин аст. Дар лоиҳаи воқеӣ барои POST-формаҳо CSRF middleware-ро фаъол карда, {% csrf_token %}-ро дар дохили формаи HTML мегузоранд. Масъалаҳои ҳадди ақали курс танзимоти пурраи лоиҳаро иваз намекунанд.
Хатоҳои маъмул ва ислоҳҳо
if form.is_valid:объекти методи ҳақиқатмонандро месанҷад ва санҷишро оғоз намекунад. Қавсҳо лозиманд:form.is_valid().request.POST["tickets"] + 1сатрро бо адад ҷамъ карда,TypeErrorмедиҳад. Баъди санҷишform.cleaned_data["tickets"]-ро гиред.clean_ticketsбеreturn ticketsқиматро баNoneиваз мекунад. Қимати дурустро баргардонед ва нодурустро боValidationErrorрад кунед.forms.EmailField()почтаро ҳатмӣ мекунад, ҳол он ки майдони анкета ихтиёрӣ аст.required=Falseгузоред; суроғаи нодурусти ғайрихолӣ ҳанӯз рад мешавад.form.save()барои формаи нодуруст пеш аз санҷишValueErrorмедиҳад. Аввалis_valid(), баъд сабт; хатоҳоро ба корбар нишон диҳед.
Ёддошт
| Вазифа | Восита |
|---|---|
| Формаи одӣ | forms.Form |
| Майдони ихтиёрӣ | required=False |
| Санҷиш / натиҷа | is_valid() / cleaned_data |
| Хатоҳо | errors, non_field_errors() |
| Санҷиши худии майдон | clean_<майдон>, ValidationError, return |
| Форма аз модел | forms.ModelForm, Meta.model, Meta.fields |
| Баъдтар сабт кардан | save(commit=False), сипас obj.save() |
| POST-и муваффақ | Сабт ва redirect(...) |