-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathchap17.xml
More file actions
769 lines (656 loc) · 36 KB
/
chap17.xml
File metadata and controls
769 lines (656 loc) · 36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[
<!ENTITY BASEID "djangobook.chap17">
]>
<chapter lang="ru" id="&BASEID;">
<title id="&BASEID;.title">
Расширение интерфейса администратора
</title>
<para>
Перевод © Попов Руслан <radz • yandex • ru>
</para>
<para>
Данная глава временно взята из первой версии книги и подлежит
корректировке. Вы можете помочь с этим!
</para>
<para>
Интерфейс администратора Django был представлен в главе
<quote><xref linkend="djangobook.chap06"
endterm="djangobook.chap06.title"/></quote>, а теперь пришло время
вернуться к нему и изучить его подробнее.
</para>
<para>
Как мы рассказывали ранее, интерфейс администратора является одной
из <quote>убийственных</quote> особенностей Django и многие
разработчики считают, что его использование сильно экономит
время. По причине большой популярности интерфейса администратора
большинство разработчиков желают настроить его для своих нужд или
расширить его функциональность.
</para>
<para>
Несколько последних разделов главы <quote><xref
linkend="djangobook.chap06"
endterm="djangobook.chap06.title"/></quote> описывают несколько
простых способов настройки определённых частей интерфейса
администратора. Давайте вспомним, о чём там было написано. Там
описывался процесс настройки списков и форм редактирования для
приведения интерфейса к стилю вашего сайта.
</para>
<para>
Также там обсуждалось, когда и зачем надо использовать интерфейс
администратора (см. главу <quote><xref
linkend="djangobook.chap06.when-why"
endterm="djangobook.chap06.when-why.title"/></quote>). Интерфейс
администратора позволяет решать такие общие задачи с минимальной
настройкой под них или вообще без неё. Но такой подход означает,
что интерфейс не может работать в других режимах редактирования.
</para>
<para>
Мы обсудим режимы для которых <emphasis>не предназначен</emphasis>
интерфейс администратора позже. Давайте сначала разберёмся в
философии.
</para>
<para>
Чтобы избежать траты времени на отладку в случае необъяснимого
сбоя в работе интерфейса администратора, рекомендую проверить
имена методов в моделях. Например, метод
<function>email()</function> в какой-нибудь модели может доставить
массу неприятных минут.
</para>
<section id="&BASEID;.zen-of-admin">
<title id="&BASEID;.zen-of-admin.title">
Дзен администрирования
</title>
<para>
По своей сути интерфейс администратора Django предназначен для
единственной работы — доверенные пользователи редактируют
структурированную информацию.
</para>
<para>
Да, это очень просто, но эта простота базируется на целом наборе
предположений. Вся философия интерфейса администратора следует
из этих предположений, так что давайте углубимся в подтекст этой
фразы в следующей секции.
</para>
<section id="&BASEID;.zen-of-admin.trusted-users">
<title id="&BASEID;.zen-of-admin.trusted-users.title">
Доверенные пользователи ...
</title>
<para>
Интерфейс администратора предназначен для использования
людьми, которым вы, разработчик,
<emphasis>доверяете</emphasis>. Это не просто означает
<quote>людей, которые были аутентифицированы</quote>, это
означает, что Django предполагает, что ваши редакторы будут
делать всё правильно.
</para>
<para>
Это, в свою очередь, означает, что не существует
утверждённого процесса редактирования информации — если
вы доверяете вашим пользователям, то никто не нуждается в
подтверждении его действий. Следующим предположением является
то, система прав доступа, мощная, не имеет поддержки для
ограничения доступа на по объектной основе. Если вы доверяете
кому-то редактировать его данные, то значит вы верите в то,
что этот пользователь не будет редактировать чужие данные без
соответствующего разрешения.
</para>
</section>
<section id="&BASEID;.zen-of-admin.editing">
<title id="&BASEID;.zen-of-admin.editing.title">
... редактируют ...
</title>
<para>
Основное назначение интерфейса администратора Django —
позволить пользователям редактировать данные. С первого
взгляда это кажется очевидным, но снова тут не всё так просто.
</para>
<para>
Например, несмотря на то, что интерфейс администратора
достаточно удобен для просмотра данных, это не учитывали при
его разработке. Вспомните недостаток права <quote>может
просматривать</quote> (см. главу <quote><xref
linkend="djangobook.chap12"
endterm="djangobook.chap12.title"/></quote>). Django
предполагает, что раз пользователям позволено просматривать
информацию через административный интерфейс, следовательно им
можно редактировать её.
</para>
<para>
Следующим важным элементом является недостаток пошагового
процесса FIXME??? Если процесс требует выполнения серии
действий, нет никакой возможности заставить пользователя
выполнить эти действия в строго определённом
порядке. Интерфейс администратора Django нацелен на
<quote>редактирование</quote>, а не на сопутствующую
активность. Также такое упразднение рабочего процесса нарушает
принцип доверия: философия интерфейса администратора такова,
что рабочий процесс является добровольным действием
пользователя, а не чем-то, что реализовано в коде.
</para>
<para>
Наконец, следует отметить недостаток возможностей обобщения
информации в интерфейсе администратора. Не существует
поддержки для отображения сумм, среднего и так далее. Снова
повторим, что интерфейс администратора предназначен для
редактирования — подразумевается, что вы напишете свои
функции представления для всего остального.
</para>
</section>
<section id="&BASEID;.zen-of-admin.structured-content">
<title id="&BASEID;.zen-of-admin.structured-content.title">
... структурированную информацию
</title>
<para>
Аналогично остальным компонентам Django, использование
интерфейса администратора подразумевает, что вы управляете
структурированными данными. Следовательно, он поддерживает
редактирование только тех данных, которые хранятся в
моделях. Для всего остального, например, для хранения данных
на файловой системе, вам потребуется реализовать собственные
функции представления.
</para>
</section>
<section id="&BASEID;.zen-of-admin.full-stop">
<title id="&BASEID;.zen-of-admin.full-stop.title">
Full Stop
</title>
<para>
Теперь должно быть очевидно, что интерфейс администратора
Django <emphasis>не пытается</emphasis> делать всё для
всех. Вместо этого мы тщательно сфокусировались на одной вещи
и делаем её очень хорошо.
</para>
<para>
Когда наступает пора расширения функциональности интерфейса
администратора Django, большая часть описанной философии
применяется и здесь (следует отметить, что такие возможности
<quote>расширения</quote> отсутствовали среди наших
целей). Так как собственные представления могут реализовывать
<emphasis>любую</emphasis> функциональность и так как они
могут легко быть визуально интегрированы в интерфейс
администратора (как описано в следующей секции), встроенные
возможности для настройки интерфейса являются чем-то
ограниченным по дизайну FIXME???
</para>
<para>
Следует помнить, что административный интерфейс является
<quote>всего лишь приложением</quote>, хотя и очень
сложным. Он не делает ничего такого, чего любой Django
разработчик при наличии достаточного времени не сможет
воспроизвести. Вполне возможно, что в будущем кто-нибудь
разработает другой интерфейс, который будет базироваться на
отличном от текущего наборе предположением и, соответственно,
будет работать иначе.
</para>
<para>
Наконец, мы должны упомянуть, что Django разработчики работают
над новой версией административного интерфейса, который
предоставит гораздо большие возможности по его настройке. Пока
вы читаете эту книгу, эти новые возможности могут быть уже
внедрены в дистрибутив Django. Просто спросите кого-нибудь из
сообщества Django, был ли интегрирована ветка
<quote>newforms-admin</quote> в общий репозиторий кода.
</para>
</section>
</section>
<section id="&BASEID;.customizing-templates">
<title id="&BASEID;.customizing-templates.title">
Настройка шаблонов интерфейса
</title>
<para>
В поставке Django поставляется набор инструментов для настройки
встроенных шаблонов интерфейса администратора, которые мы кратко
рассмотрим, но для остальных задач (таких как порядок работы с
интерфейсом или гранулированность прав доступа), вам потребуется
прочитать раздел <quote><xref linkend="&BASEID;.create-views"
endterm="&BASEID;.create-views.title"/></quote>.
</para>
<para>
Сейчас давайте рассмотрим несколько быстрых способов настройки
вида (и, частично, поведения) интерфейса администратора. В главе
<quote><xref linkend="djangobook.chap06"
endterm="djangobook.chap06.title"/></quote> описано несколько
наиболее общих задач: <quote>ребрендинг</quote> интерфейса (для
тех островолосых боссов, которые ненавидят голубой цвет) и
реализация собственных форм.
</para>
<para>
Далее появляется цель, для которой надо изменить шаблоны для
определённого элемента. Каждое представление интерфейса
администратора — списки изменений, формы редактирования,
страницы подтверждения операции удаления и страницы с историей
— имеет ассоциированный шаблон, который может быть
переопределён рядом способов.
</para>
<para>
Первый способ — можно переопределить шаблон
глобально. Представление ищет шаблон, используя стандартный
механизм загрузки шаблонов, таким образом, если вы создадите
шаблоны в одном из ваших шаблонных каталогов, Django подгрузит
их вместо стандартных. Эти глобальные шаблоны перечислены в
таблице <quote><xref linkend="&BASEID;.tbl1"
endterm="&BASEID;.tbl1.title"/></quote>:
<table id="&BASEID;.tbl1" frame="all" pgwide="1">
<title id="&BASEID;.tbl1.title">
Глобальные шаблоны интерфейса администратора
</title>
<tgroup cols="2" align="left" colsep="1" rowsep="1">
<colspec colname="c1" colwidth="6cm"/>
<colspec colname="c2" colwidth="8cm"/>
<thead>
<row rowsep="1">
<entry>Представление</entry>
<entry>Имя базового шаблона</entry>
</row>
</thead>
<tbody>
<row>
<entry>Список изменений</entry>
<entry><filename>admin/change_list.html</filename></entry>
</row>
<row>
<entry>Форма редактирования</entry>
<entry><filename>admin/change_form.html</filename></entry>
</row>
<row>
<entry>Страница подтверждение операции удаления</entry>
<entry><filename>admin/delete_confirmation.html</filename></entry>
</row>
<row>
<entry>История объекта</entry>
<entry><filename>admin/object_history.html</filename></entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
Однако большую часть времени вам будет требоваться изменить
шаблон для единственного объекта или приложения, т.е., не
глобально. Следовательно, каждое представление сначала ищет
специфичные для модели или приложения шаблоны. Эти представления
производят поиск в таком порядке:
<itemizedlist>
<listitem>
<para>
<filename><![CDATA[admin/<app_label>/<object_name>/<template>.html]]></filename>
</para>
</listitem>
<listitem>
<para>
<filename><![CDATA[admin/<app_label>/<template>.html]]></filename>
</para>
</listitem>
<listitem>
<para>
<filename><![CDATA[admin/<template>.html]]></filename>
</para>
</listitem>
</itemizedlist>
</para>
<para>
Например, представление формы редактирования для модели
<classname>Book</classname> в приложении <token>books</token>
ищет шаблоны так:
<itemizedlist>
<listitem>
<para>
<filename>admin/books/book/change_form.html</filename>
</para>
</listitem>
<listitem>
<para>
<filename>admin/books/change_form.html</filename>
</para>
</listitem>
<listitem>
<para>
<filename>admin/change_form.html</filename>
</para>
</listitem>
</itemizedlist>
</para>
<section id="&BASEID;.customizing-templates.for-models">
<title id="&BASEID;.customizing-templates.for-models.title">
Настройка шаблонов для отдельных моделей
</title>
<para>
Большую часть времени вы будете использовать первый вариант
для переопределения шаблона для отдельной модели. Это лучше
всего делать через расширение базового шаблона и добавления
информации в один из блоков, определённых в этом шаблоне.
</para>
<para>
Например, нам требуется добавить небольшой текст помощи наверх
страница с книгами. Это может выглядеть так как показано на
рисунке <quote><xref linkend="&BASEID;.pic1"
endterm="&BASEID;.pic1.title"/></quote>:
<figure id="&BASEID;.pic1" float="0">
<title id="&BASEID;.pic1.title">
Изменённая форма редактирования
</title>
<screenshot>
<mediaobject>
<imageobject>
<imagedata fileref="pics/book_extra.png" format="PNG"/>
</imageobject>
</mediaobject>
</screenshot>
</figure>
</para>
<para>
Это очень легко сделать — просто создайте шаблон с
именем
<filename>admin/bookstore/book/change_form.html</filename> и
добавьте в него следующий код:
<screen>
<![CDATA[
{% extends "admin/change_form.html" %}
{% block form_top %}
<p>Insert meaningful help message here...</p>
{% endblock %}
]]>
</screen>
</para>
<para>
Все эти шаблоны определяют ряд блоков, которые вы можете
переопределять. Как и в случае с большинством программ, лучшей
документацией является код, мы рекомендуем вам просмотреть
шаблоны административного интерфейса (они находятся в
<filename>django/contrib/admin/templates/</filename>), там
много вкусного и свежего.
</para>
</section>
<section id="&BASEID;.customizing-templates.javascript">
<title id="&BASEID;.customizing-templates.javascript.title">
Свой JavaScript
</title>
<para>
Чаще всего изменения в шаблоны отдельных моделей вносят для
того, чтобы добавить свой JavaScript на страницу —
возможно, для реализации специализированного элемента или для
выполнения какой-то работы на стороне клиента.
</para>
<para>
К счастью, это тоже не сложно. Каждый шаблон интерфейса
администратора определяет <token>{% block extrahead
%}</token>, который вы можете использовать для внедрения
дополнительной информации в элемент
<token><![CDATA[<head>]]></token>. Например, если вам
требуется подключить библиотеку <ulink
url="http://jquery.com/">jQuery</ulink> к странице с историей,
делайте так:
<screen>
<![CDATA[
{% extends "admin/object_history.html" %}
{% block extrahead %}
<script src="http://media.example.com/javascript/jquery.js"
type="text/javascript"></script>
<script type="text/javascript">
// code to actually use jQuery here...
</script>
{% endblock %}
]]>
</screen>
<note>
<para>
Мы не знаем зачем вам понадобилась jQuery на странице с
историей, но данный пример можно применить к любому
шаблону интерфейса администратора.
</para>
</note>
</para>
<para>
Вы можете использовать этот подход для подключения любых
JavaScript элементов, которые могут вам понадобится.
</para>
</section>
</section>
<section id="&BASEID;.create-views">
<title id="&BASEID;.create-views.title">
Создание своих представлений
</title>
<para>
Любой, кто ищет способ добавить своё
<emphasis>поведение</emphasis> в интерфейс администратора
Django, вероятно немного расстраивается. <quote>Всё, что вы
рассказали, относится к <emphasis>визуальному</emphasis>
преображению интерфейса</quote> — слышится их
плач. <quote>Как же мне изменить
<emphasis>функционирование</emphasis> интерфейса?</quote>
</para>
<para>
Первое, что необходимо понять, — <emphasis>в этом нет
магии</emphasis>. Следовательно интерфейс администратора не
делает ничего особенного — это просто набор представлений,
которые находятся в
<filename>django.contrib.admin.views</filename>, для
манипулирования данными.
</para>
<para>
Естественно, представления содержат немало кода в себе, который
работает со всеми этими опциями, типами полей и настройками,
которые влияют на поведение модели. Однако, как только вы
осознаете, что интерфейс администратора является простым набором
представлений, вам будет проще понять процесс добавления своего
представления.
</para>
<para>
Следуя традиции, давайте добавим представление <quote>отчет
издателя</quote> к нашему книжному приложению из главы
<quote><xref linkend="djangobook.chap06"
endterm="djangobook.chap06.title"/></quote>. Мы реализуем
представление, которое будет отображать список книг, разбитых по
издателям — очень типичный пример своего представления.
</para>
<para>
Сначала, определим наше представление в схеме URL. Следует
вставить эту строку:
<screen>
<![CDATA[
(r'^admin/books/report/$', 'mysite.books.admin_views.report'),
]]>
</screen>
<emphasis>перед</emphasis> строкой, которая подключает
представления интерфейса администратора. Весь файл со схемой URL
может выглядеть так:
<screen>
<![CDATA[
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^admin/bookstore/report/$', 'bookstore.admin_views.report'),
(r'^admin/', include('django.contrib.admin.urls')),
)
]]>
</screen>
</para>
<para>
По какой причине надо определять в схеме URL своё представление
<emphasis>до</emphasis> подключения представлений
административного интерфейса? Следует вспомнить, что Django
обрабатывает шаблоны URL по порядку. Шаблоны административного
интерфейса совпадают почти со всем, что доходит до них. Таким
образом, если мы изменим порядок этих двух строк, Django найдёт
для URL соответствующее совпадение с представлением
административного интерфейса, которое не будет работать так как
надо. В этом конкретном случае, представление попытается
подгрузить список изменений для модели
<classname>Report</classname> приложения <token>books</token>,
которого не существует.
</para>
<para>
Пришло время написать код нашего представления. Для простоты мы
будем загружать информацию обо всех книгах в контекст и позволим
шаблону управлять группировкой с помощью тега <token>{% regroup
%}</token>. Создайте файл
<filename>books/admin_views.py</filename> с таким кодом:
<screen>
<![CDATA[
from mysite.books.models import Book
from django.template import RequestContext
from django.shortcuts import render_to_response
from django.contrib.admin.views.decorators import staff_member_required
def report(request):
return render_to_response(
"admin/books/report.html",
{'book_list' : Book.objects.all()},
RequestContext(request, {}),
)
report = staff_member_required(report)
]]>
</screen>
</para>
<para>
Раз мы передали ответственность за группировку на шаблон,
представление будет очень простым. Тем не менее, существует
несколько тонких моментов, которые следует разъяснить:
<itemizedlist>
<listitem>
<para>
Мы используем декоратор
<token>staff_member_required</token> из
<token>django.contrib.admin.views.decorators</token>. Он
аналогичен декоратору <token>login_required</token>,
который был рассмотрен в главе <quote><xref
linkend="djangobook.chap12"
endterm="djangobook.chap12.title"/></quote>, но этот
декоратор также проверяет вхождение пользователя в группу
<quote>staff</quote> и, следовательно, разрешает доступ к
интерфейсу администратора.
</para>
<para>
Этот декоратор защищает все встроенные представления
административного интерфейса и организует логику
аутентификации вашего представления аналогично логике
остального интерфейса.
</para>
</listitem>
<listitem>
<para>
Мы используем шаблон из каталога
<filename>admin/</filename>. Пока явно не сказано
обратное, хорошим тоном является хранение всех
административных шаблонов в каталоге
<filename>admin/</filename>. Мы также разместили наш
шаблон в подкаталоге <filename>books</filename> —
это тоже является хорошим тоном.
</para>
</listitem>
<listitem>
<para>
Мы используем <classname>RequestContext</classname> в
качестве третьего параметра
(<token>context_instance</token>) для
<function>render_to_response()</function>. Это делает
информацию о текущем пользователе доступной в шаблоне.
</para>
<para>
Для получения подробностей о
<classname>RequestContext</classname> обратитесь к главе
<quote><xref linkend="djangobook.chap10"
endterm="djangobook.chap10.title"/></quote>.
</para>
</listitem>
</itemizedlist>
</para>
<para>
И в конце следует сделать шаблон для этого представления. Мы
будем расширять встроенные шаблоны административного интерфейса
так, чтобы визуально наше представление не отличалось от
встроенных:
<screen>
<![CDATA[
{% extends "admin/base_site.html" %}
{% block title %}List of books by publisher{% endblock %}
{% block content %}
<div id="content-main">
<h1>List of books by publisher:</h1>
{% regroup book_list|dictsort:"publisher.name" by publisher as books_by_publisher %}
{% for publisher in books_by_publisher %}
<h3>{{ publisher.grouper }}</h3>
<ul>
{% for book in publisher.list|dictsort:"title" %}
<li>{{ book }}</li>
{% endfor %}
</ul>
{% endfor %}
</div>
{% endblock %}
]]>
</screen>
</para>
<para>
Путём расширения <filename>admin/base_site.html</filename> мы
сделаем наше представление подобным стандартным, результат
показан на рисунке <quote><xref linkend="&BASEID;.pic2"
endterm="&BASEID;.pic2.title"/></quote>:
<figure id="&BASEID;.pic2" float="0">
<title id="&BASEID;.pic2.title">
Наше представление
</title>
<screenshot>
<mediaobject>
<imageobject>
<imagedata fileref="pics/books_by_publisher.png" format="PNG"/>
</imageobject>
</mediaobject>
</screenshot>
</figure>
</para>
<para>
Вы можете использовать данную методику для реализации в
административном интерфейсе всего, о чём вы только могли
мечтать. Просто не забывайте, что эти так называемые свои
представления являются простыми представлениями Django. Вы
можете использовать все методики, которые описаны в данной
книге, для создания настолько сложных представлений для
административного интерфейса, насколько это необходимо.
</para>
<para>
Мы завершим эту главу несколькими идеями по настройке
административных представлений.
</para>
</section>
<section id="&BASEID;.overriding-views">
<title id="&BASEID;.overriding-views.title">
Переопределение встроенных представлений
</title>
<para>
Временами стандартные административные представления не
вставляют. Вы легко можете подменить любое представление на своё
— просто <quote>перекройте</quote> его своим URL. В
результате ваше представление будет вызываться вместо
стандартного.
</para>
<para>
Например, мы может заменить встроенное представление формы
редактирования, на то, которое будет позволять пользователю
просто указывать ISBN книги. По ISBN коду мы затем сможем
запросить информацию о книге с сайта <ulink
url="http://isbn.nu"/> и создать объект автоматически.
</para>
<para>
Код для такого представления опущен, пусть это будет вашим
домашним заданием, но важной частью является шаблон URL:
<screen>
<![CDATA[
(r'^admin/bookstore/book/add/$', 'mysite.books.admin_views.add_by_isbn'),
]]>
</screen>
</para>
<para>
Если эта строка указана в схеме URL до подключения
административных представлений, то представление
<token>add_by_isbn</token> полностью заменит стандартное
представление.
</para>
<para>
Мы можем подменить страницу подтверждения процесса удаления,
страницу редактирования или любую другую часть интерфейса
администратора Django.
</para>
</section>
</chapter>