изглажданекрива

Има начини за модифициране и разширяване на почти всички функции на Django. Изключително рядко се налага да се пренапише значителна част от функционалността на Django само за да се промени начина, по който работи даден инструмент. Например, ако искате да промените външния вид на формуляр, можете да премахнете външния вид по подразбиране и да създадете свое собствено поле или дори просто да използвате свой собствен HTML. И в двата случая вие се възползвате от набор от функции, като същевременно запазвате всички други предимства на библиотека с форми.

Това овластяване може да бъде представено като крива. В единия край е основният случай, който е лесен за писане, но ограничава контрола. В противоположния край на кривата ще има специално изработен клас за формуляри със статичен y, който осигурява повече контрол, но също така е по-труден за създаване. В примера за създаване на формуляр тази крива ще бъде сравнително гладка, тъй като има възможности за пълната гама от функционалности на библиотеката с формуляри постепенно да замени основните опции с ваши собствени персонализирани разширения.

Преди пускането на Django 1.2 за ORM, тази крива имаше подобна форма, с едно изключение: значителен скок в края. Този скок се появи поради факта, че ако трябва да създадете нестандартен, трябва да отидете отвъд ORM. За да използва определена функционалност на ORM, потребителят ще трябва сам да я създаде отново, въпреки че това не е бедствие само по себе си. Django 1.2 добави метода Model.objects.raw(), който решава този проблем и по този начин изравнява тази крива за ORM.

Преди пускането на Django 1.2, ако трябваше да създадете SQL заявка, трябваше да напишете нещо подобно:

Не че изобщо беше такаужасно, но тук губим достъп до функционалността на ORM във всичко, което не е свързано със създаването на SQL заявки. По-специално, автоматичното преобразуване на резултатите от заявката в екземпляр на модел не е налично. Умерено отнемащи време начини за възстановяване на загубената функционалност, разбира се, съществуват, но всъщност това ще бъде изобретението на велосипеда.

Нов начин

В Django 1.2, за да създадете директна SQL заявка, трябва да напишете следното:

авторите тук ще бъдат екземпляр на RawQuerySet. RawQuerySet е подобен на QuerySet по много начини. По-специално, приликата е, че това е итерируем обект, който връща екземпляр на модела от резултатите от заявката с всяка итерация. Различава се от QuerySet по това, че не може да бъде свързан във верига. Но това тук няма значение, защото заявките вече не се генерират автоматично.

Така че това е страхотно! SQL кодът е устойчив на атаки, имаме екземпляра на модела, който искахме, и без преоткриване на колелото.

— Но това не е всичко!

Подобно на повечето инструменти на Django, методът raw() оставя място за допълнителни функции в неудобни ситуации или за особено сложни заявки:

Независим ред на полето

За метода Model.objects.raw() няма значение в какъв ред се връщат полетата при поискване. Единственото нещо, което има значение, е дали имената на полетата на заявката съвпадат с полетата в модела.

Ако в отговор на заявка получим полета, които не съществуват в класа на модела, те се добавят като анотации към онези екземпляри на модела, които методът RawQueryset връща. Това улеснява пълното използване на действия или изчисления, които се извършват по-ефективно на ниво база данни.

Дефиниции на релации между модел и полета за заявка

Ако по някаква причина не успееза точно съвпадение на имената на полетата на заявката и имената на полетата на модела, методът Model.objects.raw() предоставя опцията да го посочите ръчно.

За да съпоставите полета на заявка с полета на модел, просто трябва да използвате речник, съдържащ желаните съвпадения като един от параметрите на метода raw(). Съпоставянията трябва да се дефинират само за онези полета, които не могат да бъдат съпоставени към полета на модела.

Отложени полета

Полетата, които се очакват в модела, но не са върнати от заявката, се маркират като отложени. Те ще бъдат попълнени само при запитване към поле за екземпляр на модел. Това е полезно, когато данните не се заявяват от "истинската" таблица за модела или когато самите таблици са достатъчно големи. Това, което трябва да имате предвид тук е, че първичният ключ не може да бъде отложен и трябва да бъде върнат от всички заявки. Ако заявката не върне първичен ключ, ще бъде хвърлено изключение InvalidQuery.

Ограничения

Има някои ограничения върху действията на метода raw(). Най-важното от тях е, че методът raw() поддържа само SELECT заявки. Опитът за използване на друг тип заявка ще хвърли изключение InvalidQuery. Първоначално това беше направено за защита, но отчасти е, защото няма смисъл да се връща екземпляр на модел за нещо различно от заявка SELECT. Модифицирането на данни с директен SQL е последното нещо, което трябва да правите с Django. За да не провокираме тези действия, ние по никакъв начин не искаме да ги направим по-удобни за потребителя. Ако трябва да използвате директни SQL заявки, различни от SELECT заявка, винаги имате опцията да създадете курсор на база данни и да работите оттам.

Hardcore conf в C++. Каним само професионалисти.