Why I Hate Django | Information Technology Management | Areas Of Computer Science

Why I Hate Django

Cal Henderson

O HAI

DjangoCon 2008

2

My happy face
DjangoCon 2008 3

DjangoCon 2008

4

2.8 billion photos

DjangoCon 2008

5

2.8 billion photos

1 per 2.3 people on earth 9.2 per US resident
DjangoCon 2008 6

35k photos/sec >2m photos/min

DjangoCon 2008

7

Many thousand pages/sec
DjangoCon 2008 8

Scale nerd

DjangoCon 2008

9

Serious Language
DjangoCon 2008 10

Wordpress Yahoo

Mediawiki
DjangoCon 2008

Facebook
11

Wordpress Yahoo Digg Delicious

Mediawiki
DjangoCon 2008

Facebook
12

Flamework Serious Toolset

DjangoCon 2008

13

Flamework Flint Flinderbox Flaux Flag
DjangoCon 2008

Flink Flotos Flictionary Flops Fleng
14

Why hate Django?
DjangoCon 2008 15

What does he even know about Django?

DjangoCon 2008

16

Pownce
DjangoCon 2008 17

A fucking blogging engine

DjangoCon 2008

18

Why all the hate?

DjangoCon 2008

19

DjangoCon 2008

20

DjangoCon 2008

21

DjangoCon 2008

22

DjangoCon 2008

23

An attack on several fronts

DjangoCon 2008

24

An attack on several fronts

The team Python Frameworks
DjangoCon 2008 25

Django itself

Performance Scalability Maintainability
DjangoCon 2008 26

The Team
DjangoCon 2008 27

Frameworks

DjangoCon 2008

28

Struts
DjangoCon 2008 29

Craig McClanahan
DjangoCon 2008 30

DjangoCon 2008

31

Exhibit A : Beard

DjangoCon 2008

32

But Struts is for suits!
DjangoCon 2008 33

The Hot Shit
DjangoCon 2008 34

DjangoCon 2008

35

Rails = Badass

DjangoCon 2008

36

Instead?

A boy band?
DjangoCon 2008 37

DjangoCore The Album

DjangoCon 2008

38

DjangoCon 2008

39

Also, a wizard

Simon “Stinky” Willison
DjangoCon 2008 40

Python
DjangoCon 2008 41

Trendy

Google!
DjangoCon 2008 42

But not that trendy

DjangoCon 2008

43

But not that trendy It’s no ruby

DjangoCon 2008

44

But not that trendy It’s no ruby Or Haskell
DjangoCon 2008 45

But not that trendy It’s no ruby Or Haskell Or Erlang
DjangoCon 2008 46

But not that trendy It’s no ruby Or Haskell Or Erlang Or Scala
DjangoCon 2008 47

Significant Whitespace

DjangoCon 2008

48

DjangoCon 2008

49

Salmon

DjangoCon 2008

50

Universe of marshy force. Field sense shallows the hatchery saying Hello,. World!. Hydro. Power spring sometimes; snowmelt powers snowmelt always.

DjangoCon 2008

51

DjangoCon 2008

52

No quantum superpositions

DjangoCon 2008

53

DjangoCon 2008

54

“-”.join(array)

DjangoCon 2008

55

Restarting the server?

WTF!?
DjangoCon 2008 56

WSGIReloadMechanism
DjangoCon 2008 57

“I buy my eggs at the cheese shop”
- Aaron Straup Cope

DjangoCon 2008

58

“I buy my eggs at the cheese shop”
- Aaron Straup Cope

N O O [M
DjangoCon 2008

N A L

] E G A U G

59

DjangoCon 2008

60

__import__()

from future import awesome

DjangoCon 2008

61

Basically, for hippies

Scared of real OO languages
DjangoCon 2008 62

Frameworks
DjangoCon 2008 63

Flamework is a framework

But what does that mean?

DjangoCon 2008

64

Make common tasks:

easier faster error-free

DjangoCon 2008

65

Show a list of photos Write an API method Kill all humans

DjangoCon 2008

66

Front-tier frameworks

Act as glue
DjangoCon 2008 67

Other Services

Data store

Data Model

Business Logic

Request Dispatcher

Interaction Logic

Templates

Framework Users
DjangoCon 2008 68

Great for getting started

Slows you down later?

What is it doing in there?
DjangoCon 2008 69

DjangoCon 2008

70

DjangoCon 2008

71

DjangoCon 2008

72

Fast

Easy

Flexible
DjangoCon 2008

Scalable
73

Large scale is often not a good goal
DjangoCon 2008 74

Skyscrapers are special

DjangoCon 2008

75

Regular houses Don’t need 10 story foundations

DjangoCon 2008

76

Just build!

DjangoCon 2008

77

DjangoCon 2008

78

DjangoCon 2008

79

DjangoCon 2008

80

Everything here is possible!

We care about easy
DjangoCon 2008 81

Large Scale
DjangoCon 2008 82

No multiple DB clusters

DjangoCon 2008

83

Manual partitioning
DjangoCon 2008 84

No multiple hosts per DB
DjangoCon 2008 85

Where do we read from?

DjangoCon 2008

86

How about now?

DjangoCon 2008

87

How about now ?

DjangoCon 2008

88

Read/write consistency

DjangoCon 2008

89

Read/write consistency

LAG!!1
DjangoCon 2008 90

Good for non-writing users

(logged out)
DjangoCon 2008 91

Non time-sensitive data

Feeds Read-only APIs
DjangoCon 2008 92

DjangoCon 2008

93

Cool kids use master/master pairs
DjangoCon 2008 94

Consistent read/write

1. Write to side A 2. Read from side B 3. Replication occurs 4. FAIL
DjangoCon 2008 95

Consistent read/write

1. Write to side A 2. Read from side A 3. ??? 4. PROFIT!!
DjangoCon 2008 96

Then we can start to get fancy!
DjangoCon 2008 97

Where do we read/write?

DjangoCon 2008

98

Abstraction FTW

db_query($cluster_name, $sql)

DjangoCon 2008

99

No sharding
DjangoCon 2008 100

WTF is sharding?

All about books
DjangoCon 2008 101

Dewey Decimal
DjangoCon 2008 102

But it can’t do everything

DjangoCon 2008

103

Makes some things ‘impossible’

No shard walking
DjangoCon 2008 104

DjangoCon 2008

105

Django knows our models

It’s possible
DjangoCon 2008 106

If we accept constraints

DjangoCon 2008

107

No external sequences
DjangoCon 2008 108

Auto-incs can be bad

master/master shards
DjangoCon 2008 109

No automatic denormalization

DjangoCon 2008

110

Counters would be easy!
DjangoCon 2008 111

And copied fields too

DjangoCon 2008

112

High Performance
DjangoCon 2008 113

It’s slow!

DjangoCon 2008

114

DjangoCon 2008

115

DjangoCon 2008

116

There are limits

But they only apply When being really silly
DjangoCon 2008 117

Sessions

DjangoCon 2008

118

OMG UR ON CRAK
DjangoCon 2008 119

Extra DB table

A read on every page
DjangoCon 2008 120

Lightweight = better

DjangoCon 2008

121

Signed cookies
DjangoCon 2008 122

No parallelization
DjangoCon 2008 123

Multiple cache-requests
DjangoCon 2008 124

Multiple multi-keyed reads

DjangoCon 2008

125

Slow HTTP requests while we’re doing other stuff

DjangoCon 2008

126

Creates dumb SQL

DjangoCon 2008

127

foo.exclude(bar = true) WHERE (NOT (bar = 1))
DjangoCon 2008 128

foo.exclude(bar = true) WHERE bar != 1
DjangoCon 2008 129

foo.filter(bar = false) WHERE bar = 0

Indexable!
DjangoCon 2008 130

Maintainability
DjangoCon 2008 131

Maintainability Awesomeness
DjangoCon 2008 132

Verbose template syntax

<h1>{{ foo.bar }}</h1>
DjangoCon 2008 133

<h1>{{ foo.bar }}</h1> <h1>{$foo.bar}</h1> 3 extra characters!
DjangoCon 2008 134

<h1>{{ foo.bar }}</h1> <h1>{$foo.bar|e}</h1> Well almost…
DjangoCon 2008 135

{% if edit_mode %} woo {% endif %}

9 extra!
DjangoCon 2008

{if $edit_mode} woo {/if}
136

Verbose template syntax makes people cry

DjangoCon 2008

137

No query debugger
DjangoCon 2008 138

>>> from django.db import connection >>> connection.queries [{'sql': 'SELECT polls_polls.id,polls_polls.question,polls_ polls.pub_date FROM polls_polls', 'time': '0.002'}]

DjangoCon 2008

139

>>> from django.db import connection >>> connection.queries [{'sql': 'SELECT polls_polls.id,polls_polls.question,polls_ polls.pub_date FROM polls_polls', 'time': '0.002'}]

Not good enough!
DjangoCon 2008 140

Better, but not amazing

DjangoCon 2008

141

DjangoCon 2008

142

Page summary

DjangoCon 2008

143

Make it clickable…

DjangoCon 2008

144

EXPLAIN is AWESOME
DjangoCon 2008 145

And/or show the data

DjangoCon 2008

146

MySQL Query Profiler

Enough data to choke a whale
DjangoCon 2008 147

Not smug enough

DjangoCon 2008

148

DjangoCon 2008

149

DjangoCon 2008

150

Unreadable SQL
SELECT `app_userprofile`.`user_id`,`app_userprofile`.`account_status`,`app_userp rofile`.`account_status_reason`,`app_userprofile`.`account_delete_type`,` app_userprofile`.`syndication_key`,`app_userprofile`.`blurb`,`app_userpro file`.`location`,`app_userprofile`.`country`,`app_userprofile`.`postal_code`,` app_userprofile`.`gender`,`app_userprofile`.`theme`,`app_userprofile`.`tiny _photo`,`app_userprofile`.`small_photo`,`app_userprofile`.`smedium_pho to`,`app_userprofile`.`medium_photo`,`app_userprofile`.`large_photo`,`ap p_userprofile`.`orig_photo`,`app_userprofile`.`bday_month`,`app_userpro file`.`bday_day`,`app_userprofile`.`bday_year`,`app_userprofile`.`is_pro`,`a pp_userprofile`.`privacy_settings_id`,`app_userprofile`.`email_settings_id `,`app_userprofile`.`preference_settings_id`,`app_userprofile`.`ad_counte r`,`app_userprofile`.`num_friends`,`app_userprofile`.`num_fans`,`app_user profile`.`num_feeds`,`app_userprofile`.`num_blocked_fans`,`app_userpro file`.`num_friend_requests`,`app_userprofile`.`default_set_id`,`app_userpr ofile`.`invite_id`,`app_userprofile`.`invite_round`,`app_userprofile`.`avail_in vites`,`app_userprofile`.`original_email` FROM `app_userprofile` WHERE (`app_userprofile`.`user_id` = 1)

DjangoCon 2008

151

Unreadable SQL
SELECT * FROM `app_userprofile` WHERE `user_id` = 1

DjangoCon 2008

152

SELECT * is fast! Faster over the wire Faster to parse Easier to debug
DjangoCon 2008 153

Unreadable SQL
SELECT `app_note`.`id`,`app_note`.`type`,`app_note`.`body`,`app_note `.`sender_id`,`app_note`.`date_sent`,`app_note`.`num_recipie nts`,`app_note`.`recipient_type`,`app_note`.`set_id`,`app_not e`.`direct_to_id`,`app_note`.`media_file_id`,`app_note`.`url`,`a pp_note`.`url_inline`,`app_note`.`url_clicks`,`app_note`.`embe d_id`,`app_note`.`event_id`,`app_note`.`is_direct`,`app_note`.` is_public`,`app_note`.`is_deleted`,`app_note`.`is_ad`,`app_no te`.`reply_to_id`,`app_note`.`forwarded_from_id`,`app_note`.` original_note_id`,`app_note`.`stars`,`app_note`.`rsvp` FROM `app_note` LEFT OUTER JOIN `app_userprofile_notes` AS `m2m_app_note__recipients` ON `app_note`.`id` = `m2m_app_note__recipients`.`note_id` WHERE ((NOT (`app_note`.`is_deleted` = True)) AND `m2m_app_note__recipients`.`userprofile_id` = 17573) ORDER BY `app_note`.`date_sent` DESC LIMIT 16
DjangoCon 2008 154

Unreadable SQL
SELECT n.* FROM app_note AS n LEFT OUTER JOIN app_userprofile_notes AS l ON n.id=l.note_id WHERE n.is_deleted = False AND l.userprofile_id=17573 ORDER BY n.date_sent DESC LIMIT 16
DjangoCon 2008 155

Django makes me

scared of joins
DjangoCon 2008 156

Actually, JOINs are evil
DjangoCon 2008 157

DjangoCon 2008

158

Low version number

DjangoCon 2008

159

DjangoCon 2008

160

DjangoCon 2008

161

Suspiciously small

Django: 105 klocs Flamework: 260 klocs
DjangoCon 2008 162

Suspiciously small

Very long lines?
DjangoCon 2008 163

Can’t pluralize octopus
DjangoCon 2008 164

Commit all fields at once

DjangoCon 2008

165

Race conditions!
DjangoCon 2008 166

Dirty flags
DjangoCon 2008 167

Don’t make Malcolm cry
DjangoCon 2008 168

No simple way to inc/dec

DjangoCon 2008

169

UPDATE foo SET x=x+1

Makes consistency hard!
DjangoCon 2008 170

Character encoding Input validation?

DjangoCon 2008

171

Character encoding Input validation?
(Probably broken)

DjangoCon 2008

172

No mascot!?!

DjangoCon 2008

173

Echidna?

DjangoCon 2008

174

MAGICAL POWERS

DjangoCon 2008

175

No deployment system

DjangoCon 2008

176

Extending models

Tables are never big enough
DjangoCon 2008 177

Model changes

manage.py reset appname

DjangoCon 2008

178

django-evolution

dmigrations
DjangoCon 2008 179

What’s django done for you lately?
DjangoCon 2008 180

thanks
(now go make it better)

Photo credits
• • • • • • • • • • • • • • • • • • • • • • • • •

flickr.com/photos/wilson/18685396/ flickr.com/photos/uhop/105063089/ flickr.com/photos/plasticbag/91453376/ flickr.com/photos/zenoc/1408162618/ flickr.com/photos/subinev/27810058/ flickr.com/photos/kaptainkobold/2531797176/ flickr.com/photos/esti/243781036/ flickr.com/photos/oneras/253617128/ flickr.com/photos/josefstuefer/72512671/ flickr.com/photos/pgoyette/168076182/ flickr.com/photos/paulhammond/2825869449/ flickr.com/photos/nez/378348754/ flickr.com/photos/calevans/2265863104/ flickr.com/photos/mbiddulph/416190643/ flickr.com/photos/obliterated/2249663391/ flickr.com/photos/salim/67753003/ flickr.com/photos/sosalem/2816909110/ flickr.com/photos/radiorover/324193883/ flickr.com/photos/nickwheeleroz/2773776799/ flickr.com/photos/rse/22972901/ flickr.com/photos/rougerouge/534615363/ flickr.com/photos/hawkexpress/386355092/ flickr.com/photos/escalla/438817719/ flickr.com/photos/mknightphoto/2295688304/ flickr.com/photos/petereed/138369750/

• • • • • • • • • • • • • • • • • • • • • • • • • •

flickr.com/photos/sharynmorrow/2571566304/ flickr.com/photos/florathexplora/286035943/ flickr.com/photos/webguru4god/2233500779/ flickr.com/photos/emdot/195189924/ flickr.com/photos/kayepants/391645870/ flickr.com/photos/ppowers/793939285/ flickr.com/photos/dinesh_valke/425540358/ flickr.com/photos/hawkexpress/306276212/ flickr.com/photos/cedric1981/383614033/ flickr.com/photos/macspite/1118042091/ flickr.com/photos/jpstanley/1440357613/ flickr.com/photos/ashclements/248887492/ flickr.com/photos/kecko/1876479840/ flickr.com/photos/difusa/131100622/ flickr.com/photos/amagill/378984660/ flickr.com/photos/bea_k63w-wa/2466009108/ flickr.com/photos/namullim/2096115820/ flickr.com/photos/lotterymonkey/175248733/ flickr.com/photos/13519089@N03/1380483002/ flickr.com/photos/gswj/10344097/ flickr.com/photos/deanj/67607256/ flickr.com/photos/malias/2218694639/ flickr.com/photos/clintjcl/120760767/ flickr.com/photos/grandpamikey/2228239585/ flickr.com/photos/lea/2829752510/ flickr.com/photos/superamit/196481424/ 182

DjangoCon 2008

More photo credits
• • • • • • • • • • • • • • • • • • • • • • • • • •

flickr.com/photos/simon999/2419051858/ flickr.com/photos/tonyjcase/2172060723/ flickr.com/photos/heypaul/1428681/ flickr.com/photos/swisscan/2308034084/ flickr.com/photos/apollonia666/310793656/ flickr.com/photos/bdorfman/15846725/ flickr.com/photos/wishymom/566394520/ flickr.com/photos/jgarber/121886004/ flickr.com/photos/eole/380316678/ flickr.com/photos/917press/1940509163/ flickr.com/photos/wallyg/476718069/ flickr.com/photos/biwook/390088839/ flickr.com/photos/bdjsb7/1674027307/ flickr.com/photos/naveenroy/314965221/ flickr.com/photos/wyldkyss/2757474674/ flickr.com/photos/orinrobertjohn/409812627/ flickr.com/photos/candiedwomanire/1651870/ flickr.com/photos/dalvenjah/408497650/ flickr.com/photos/krikit/2657457178/ flickr.com/photos/w5nyv/2370344/ flickr.com/photos/jordanfischer/72510316/ flickr.com/photos/tedsblog/91531710/ flickr.com/photos/celesterc/1069893367/ flickr.com/photos/spacematters/766372252/ flickr.com/photos/esti/147733640/ flickr.com/photos/rbp/2833593771/

• • • • • • • • • • • • • • • • • • • • • • • • • •

flickr.com/photos/jordanroher/228435564/ flickr.com/photos/tambako/2524829095/ flickr.com/photos/66132721@N00/2725908636/ flickr.com/photos/freeparking/1279927021/ flickr.com/photos/drurydrama/1352506223/ flickr.com/photos/mn_francis/397620193/ flickr.com/photos/dramaqueennorma/273371415/ flickr.com/photos/chasqui/2338990305/ flickr.com/photos/cityhunter12/2574288725/ flickr.com/photos/akbuthod/1508537255/ flickr.com/photos/nunoforos/2811186142/ flickr.com/photos/marcusjb/432600086/ flickr.com/photos/12495774@N02/2405297371/ flickr.com/photos/larimdame/572477975/ flickr.com/photos/harryharris/1525946537/ flickr.com/photos/davemorris/91808851/ flickr.com/photos/aplumb/121285138/ flickr.com/photos/peebot/825451566/ flickr.com/photos/reillyb/2216541900/ flickr.com/photos/steffe/423086866/ flickr.com/photos/ciordia/255983919/ flickr.com/photos/wwworks/2472230611/ flickr.com/photos/pnoid00/1909096140/ flickr.com/photos/jurvetson/2229899/ flickr.com/photos/foxypar4/766801643/ flickr.com/photos/wizardhere/2413404079/ 183

DjangoCon 2008

these slides are online:

iamcal.com/talks

DjangoCon 2008

184

Sign up to vote on this title
UsefulNot useful