Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Django Admin: Widgetry & Witchery
Search
Pamela Fox
August 31, 2012
Technology
4
1.6k
Django Admin: Widgetry & Witchery
Why we chose to use Django admin, and how it worked, and, well, how it didn't work.
Pamela Fox
August 31, 2012
Tweet
Share
More Decks by Pamela Fox
See All by Pamela Fox
Enterprise AI in 2025?
pamelafox
0
310
Fast-track your AI app development with GitHub and Azure
pamelafox
1
190
GitHub Universe: Evaluating RAG apps in GitHub Actions
pamelafox
0
500
Learn Live: Creating a Website using GitHub Copilot
pamelafox
1
280
O'Reilly Superstream: Building a RAG App to Chat with Your Data
pamelafox
1
430
AI Tour Mexico: Production-ready RAGwith Azure AI Search
pamelafox
1
370
AI Tour Mexico: Securing AI Apps on Azure
pamelafox
0
810
RAGHack: Kickoff and RAG 101
pamelafox
1
830
RAGHack: Building RAG apps in Python
pamelafox
1
470
Other Decks in Technology
See All in Technology
AWS CDK の目玉新機能「Mixins」とは / cdk-mixins
gotok365
2
320
Sansan Engineering Unit 紹介資料
sansan33
PRO
1
4k
問い合わせ自動化の技術的挑戦
recruitengineers
PRO
2
120
Microsoft Fabric のワークスペースと容量の設計原則
ryomaru0825
2
230
オンプレとGoogle Cloudを安全に繋ぐための、セキュア通信の勘所
waiwai2111
3
1.1k
マイグレーションガイドに書いてないRiverpod 3移行話
taiju59
0
340
ブラックボックス観測に基づくAI支援のプロトコルのリバースエンジニアリングと再現~AIを用いたリバースエンジニアリング~ @ SECCON 14 電脳会議 / Reverse Engineering and Reproduction of an AI-Assisted Protocol Based on Black-Box Observation @ SECCON 14 DENNO-KAIGI
chibiegg
0
130
チームメンバー迷わないIaC設計
hayama17
5
3.6k
作るべきものと向き合う - ecspresso 8年間の開発史から学ぶ技術選定 / 技術選定con findy 2026
fujiwara3
6
1.7k
Bill One 開発エンジニア 紹介資料
sansan33
PRO
5
18k
AIに視覚を与えモバイルアプリケーション開発をより円滑に行う
lycorptech_jp
PRO
1
760
Agentic Codingの実践とチームで導入するための工夫
lycorptech_jp
PRO
0
380
Featured
See All Featured
The Language of Interfaces
destraynor
162
26k
Ruling the World: When Life Gets Gamed
codingconduct
0
160
Designing for Timeless Needs
cassininazir
0
150
Building Adaptive Systems
keathley
44
2.9k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3.4k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
97
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
0
580
The Invisible Side of Design
smashingmag
302
51k
30 Presentation Tips
portentint
PRO
1
250
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
1
1.3k
The browser strikes back
jonoalderson
0
750
Transcript
Django Admin Widgetry & Witchery Pamela Fox @pamelafox Thursday, August
30, 12
Coursera: What we do Thursday, August 30, 12
Our Backend Thursday, August 30, 12
Why We Need Admin Thursday, August 30, 12
Why Django Admin? Creates forms for adding/editing/searching models Restricts fields
based on admin roles Thursday, August 30, 12
How Django Admin Works https://docs.djangoproject.com/en/dev/ref/contrib/admin/ from django.contrib import admin from
app import admin from app.courses.models import Course from app.courses.forms import CourseAdminForm class CourseAdmin(ModelAdmin): base_model = Course restrict_fields = ['instructors', 'teaching_assistants', ] form = CourseAdminForm fieldsets = [ (None, { 'fields': [ 'name', 'topic', 'active', ] }), ('Dates', { 'fields': [ 'start_date', 'end_date', 'start_date_string', 'duration_string', ] }) ] admin.site.register(Course, CourseAdmin) Thursday, August 30, 12
...And a few words on how it doesn’t work. Thursday,
August 30, 12
☹: The Look & Feel != Thursday, August 30, 12
Solution: Twitter Bootstrap https://github.com/gkuhn1/django-admin-templates-twitter-bootstrap Thursday, August 30, 12
☹: The Default Widgets BooleanField CharField ChoiceField TypedChoiceField DateField DateTimeField
DecimalField EmailField FileField FilePathField FloatField ImageField IntegerField IPAddressField GenericIPAddressField MultipleChoiceField TypedMultipleChoiceField NullBooleanField RegexField SlugField TimeField URLField ComboField MultiValueField SplitDateTimeField ModelChoiceField ModelMultipleChoiceField Thursday, August 30, 12
Solution: Custom Widgets WysiHTMLEditor TransloaditUpload UniqueShortName NumberField NumberRangeField AutoCompleteTextInput Thursday,
August 30, 12
Custom Widgets class NumberField(HiddenInput): class Media: js = ( settings.ADMIN_MEDIA_PREFIX
+ 'js/numberfields.js', ) def render(self, name, value, attrs=None): input = super(NumberField, self).render(name, value, attrs=attrs) final_attrs = self.build_attrs(attrs) units = final_attrs.get('units', '') html = u""" <div class="number-field"> %(input)s <input type="number" min="1" class="number-range-field-num input-mini"> <span class="number-range-field-units">%(units)s<span> </div> """ % {'input': input, 'units': units} return mark_safe(html) admin/common/widgets.py: from django.forms import ModelForm from app.common.widgets import NumberField class CourseAdminForm(ModelForm): class Meta: widgets = { 'duration_string': NumberField( attrs={'units': 'weeks'}) } course/forms.py from app import admin from app.courses.models import Course from app.courses.forms import CourseAdminForm class CourseAdmin(ModelAdmin): base_model = Course form = CourseAdminForm course/admin.py Thursday, August 30, 12
☹: Default Save Options != Thursday, August 30, 12
Solution: Horrible Hacks var topicPageRegEx = /\/topics\/topic\//i; var isTopicPage =
topicPageRegEx.exec(window.location.href); if (isTopicPage) { var previewHosts = {'admin': 'site', 'admin.coursera.org': 'www.coursera.org'}; var previewUrl = 'http://' + previewHosts[window.location.host] + '/course/' + $ ('input[name="short_name"]').val(); var $previewUrl = $('<input type="hidden" name="_previewurl">').val(previewUrl); var $previewButton = $('<input type="submit" name="_saveandpreview" value="Save and Preview" class="btn btn-info">'); var $saveButton = $('.form-actions input[name="_save"]') $saveButton.after(' ').after($previewButton) .after(' ').after($previewUrl); } templates/admin/change_form.html if "_saveandpreview" in request.POST: return HttpResponseRedirect(request.POST['_previewurl']) admin/options.py Thursday, August 30, 12
In conclusion... Thursday, August 30, 12
Our Future Admin Stack? https://github.com/PaulUithol/backbone-tastypie https://github.com/joshbohde/django-backbone-example Thursday, August 30, 12