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.5k
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
Fast-track your AI app development with GitHub and Azure
pamelafox
1
41
GitHub Universe: Evaluating RAG apps in GitHub Actions
pamelafox
0
300
Learn Live: Creating a Website using GitHub Copilot
pamelafox
1
74
O'Reilly Superstream: Building a RAG App to Chat with Your Data
pamelafox
1
230
AI Tour Mexico: Production-ready RAGwith Azure AI Search
pamelafox
1
230
AI Tour Mexico: Securing AI Apps on Azure
pamelafox
0
310
RAGHack: Kickoff and RAG 101
pamelafox
1
540
RAGHack: Building RAG apps in Python
pamelafox
1
290
Deploying an AI App to aPrivate Network on Azure
pamelafox
1
170
Other Decks in Technology
See All in Technology
[Ruby] Develop a Morse Code Learning Gem & Beep from Strings
oguressive
1
190
PHP ユーザのための OpenTelemetry 入門 / phpcon2024-opentelemetry
shin1x1
3
1.4k
なぜCodeceptJSを選んだか
goataka
0
180
生成AIのガバナンスの全体像と現実解
fnifni
1
210
OCI技術資料 : ファイル・ストレージ 概要
ocise
3
11k
2024年にチャレンジしたことを振り返るぞ
mitchan
0
150
組織に自動テストを書く文化を根付かせる戦略(2024冬版) / Building Automated Test Culture 2024 Winter Edition
twada
PRO
18
5.6k
20241220_S3 tablesの使い方を検証してみた
handy
4
700
いまからでも遅くないコンテナ座学
nomu
0
130
私なりのAIのご紹介 [2024年版]
qt_luigi
1
120
多領域インシデントマネジメントへの挑戦:ハードウェアとソフトウェアの融合が生む課題/Challenge to multidisciplinary incident management: Issues created by the fusion of hardware and software
bitkey
PRO
2
120
怖くない!ゼロから始めるPHPソースコードコンパイル入門
colopl
0
160
Featured
See All Featured
How GitHub (no longer) Works
holman
311
140k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
2
290
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
120k
Imperfection Machines: The Place of Print at Facebook
scottboms
266
13k
Put a Button on it: Removing Barriers to Going Fast.
kastner
59
3.6k
The Language of Interfaces
destraynor
154
24k
A Tale of Four Properties
chriscoyier
157
23k
Building Applications with DynamoDB
mza
91
6.1k
Side Projects
sachag
452
42k
Adopting Sorbet at Scale
ufuk
73
9.1k
How To Stay Up To Date on Web Technology
chriscoyier
789
250k
Speed Design
sergeychernyshev
25
680
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