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
320
Fast-track your AI app development with GitHub and Azure
pamelafox
1
200
GitHub Universe: Evaluating RAG apps in GitHub Actions
pamelafox
0
510
Learn Live: Creating a Website using GitHub Copilot
pamelafox
1
290
O'Reilly Superstream: Building a RAG App to Chat with Your Data
pamelafox
1
440
AI Tour Mexico: Production-ready RAGwith Azure AI Search
pamelafox
1
380
AI Tour Mexico: Securing AI Apps on Azure
pamelafox
0
820
RAGHack: Kickoff and RAG 101
pamelafox
1
850
RAGHack: Building RAG apps in Python
pamelafox
1
480
Other Decks in Technology
See All in Technology
The Rise of Browser Automation: AI-Powered Web Interaction in 2026
marcthompson_seo
0
310
欠陥分析(ODC分析)における生成AIの活用プロセスと実践事例 / 20260320 Suguru Ishii & Naoki Yamakoshi & Mayu Yoshizawa
shift_evolve
PRO
0
390
CloudFrontのHost Header転送設定でパケットの中身はどう変わるのか?
nagisa53
1
160
Kubernetesの「隠れメモリ消費」によるNode共倒れと、Request適正化という処方箋
g0xu
0
110
20260321_エンベディングってなに?RAGってなに?エンベディングの説明とGemini Embedding 2 の紹介
tsho
0
160
テストプロセスにおけるAI活用 :人間とAIの共存
hacomono
PRO
0
160
Phase05_ClaudeCode入門
overflowinc
0
2k
Phase11_戦略的AI経営
overflowinc
0
1.5k
データマネジメント戦略Night - 4社のリアルを語る会
ktatsuya
1
220
スピンアウト講座04_ルーティン処理
overflowinc
0
1.1k
スピンアウト講座02_ファイル管理
overflowinc
0
1.2k
BFCacheを活用して無限スクロールのUX を改善した話
apple_yagi
0
120
Featured
See All Featured
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
250
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.6k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.4k
Why Our Code Smells
bkeepers
PRO
340
58k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
650
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
320
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
300
The Limits of Empathy - UXLibs8
cassininazir
1
270
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
250
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.2k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
330
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