Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
Django Admin: Widgetry & Witchery
Pamela Fox
August 31, 2012
Technology
4
1.3k
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
Education for All
pamelafox
0
190
CS+SocialGood: Education
pamelafox
0
24
Fight Tech with Tech: Take Control of Your Digital Environment
pamelafox
1
200
Coding Everywhere
pamelafox
1
250
Beware the Near Enemies
pamelafox
0
110
Cultivating Empathetic Joy: An Antidote to Jealousy and Judgment
pamelafox
0
340
JS Freakin' Everywhere: A Chatbot Powered by AWS+NodeJS
pamelafox
0
350
Pamela Fox: Learner, Creator, Teacher
pamelafox
1
370
Massive Online Learning Challenges
pamelafox
1
280
Other Decks in Technology
See All in Technology
2年で10→70人へ! スタートアップの 情報セキュリティ課題と施策
miekobayashi
1
410
金属加工屋の営業マンがSTマイクロで・・・
usashirou
0
160
IoT から見る AWS re:invent 2022 ― AWSのIoTの歴史を添えて/Point of view the AWS re:invent 2022 with IoT - with a history of IoT in AWS
ma2shita
0
250
WebLogic Server for OCI 概要
oracle4engineer
PRO
3
870
組織に対してSREを適用するとどうなるか
kuniim
1
230
CES_2023_FleetWise_demo.pdf
sparkgene
0
110
Optimizing your Swift code
kateinoigakukun
0
1.4k
USB PD で迎える AC アダプター大統一時代
puhitaku
2
1.9k
経営統合をきっかけに会社をエンジニアリングした話 / btconjp-2023
carta_engineering
0
150
ECテックカンファレンス2023 EC事業部のモバイル開発2023
tatsumi0000
0
280
PCI DSS に準拠したシステム開発
yutadayo
0
310
Stripe / Okta Customer Identity Cloud(旧Auth0) の採用に至った理由 〜モリサワの SaaS 戦略〜
tomuro
0
120
Featured
See All Featured
What's new in Ruby 2.0
geeforr
336
30k
Done Done
chrislema
178
14k
GraphQLとの向き合い方2022年版
quramy
20
9.9k
How GitHub Uses GitHub to Build GitHub
holman
465
280k
The Pragmatic Product Professional
lauravandoore
21
3.4k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
13
1.1k
Streamline your AJAX requests with AmplifyJS and jQuery
dougneiner
128
8.8k
A Philosophy of Restraint
colly
193
15k
Large-scale JavaScript Application Architecture
addyosmani
499
110k
Raft: Consensus for Rubyists
vanstee
130
5.7k
Designing for Performance
lara
600
65k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
6
840
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