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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Pamela Fox
August 31, 2012
Technology
1.6k
4
Share
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
More Decks by Pamela Fox
See All by Pamela Fox
Enterprise AI in 2025?
pamelafox
0
330
Fast-track your AI app development with GitHub and Azure
pamelafox
1
210
GitHub Universe: Evaluating RAG apps in GitHub Actions
pamelafox
0
520
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
390
AI Tour Mexico: Securing AI Apps on Azure
pamelafox
0
830
RAGHack: Kickoff and RAG 101
pamelafox
1
880
RAGHack: Building RAG apps in Python
pamelafox
1
490
Other Decks in Technology
See All in Technology
ネットワーク運用を楽にするAWS DevOps Agent活用法!! / 20260421 Masaki Okuda
shift_evolve
PRO
2
190
最新の脅威動向から考える、コンテナサプライチェーンのリスクと対策
kyohmizu
1
650
CloudSec JP #005 後締め ~ソフトウェアサプライチェーン攻撃から開発者のシークレットを守る~
lhazy
0
220
JOAI2026講評会資料(近藤佐介)
element138
1
160
All About Sansan – for New Global Engineers
sansan33
PRO
1
1.4k
Master Dataグループ紹介資料
sansan33
PRO
1
4.6k
#jawsugyokohama 100 LT11, "My AWS Journey 2011-2026 - kwntravel"
shinichirokawano
0
310
AI時代にデータ基盤が持つべきCapabilityを考える + Snowflake Data Superheroやっていき宣言 / Considering the Capabilities Data Platforms Should Have in the AI Era + Declaration of Commitment as a Snowflake Data Superhero
civitaspo
0
110
扱える不確実性を増やしていく - スタートアップEMが考える「任せ方」
kadoppe
0
250
Amazon S3 Filesについて
yama3133
2
180
生成AI時代のエンジニア育成 変わる時代と変わらないコト
starfish719
0
8.9k
NOSTR, réseau social et espace de liberté décentralisé
rlifchitz
0
200
Featured
See All Featured
The untapped power of vector embeddings
frankvandijk
2
1.7k
Chasing Engaging Ingredients in Design
codingconduct
0
170
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
210
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
61k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
0
1.1k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
510
エンジニアに許された特別な時間の終わり
watany
106
240k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.2k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
810
So, you think you're a good person
axbom
PRO
2
2k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.2k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
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