Why I Hate Django

Preview:

DESCRIPTION

 

Citation preview

Why I Hate DjangoCal Henderson

DjangoCon 2008 2

O HAI

DjangoCon 2008 3

My happy face

DjangoCon 2008 4

DjangoCon 2008 5

2.8 billion photos

DjangoCon 2008 6

2.8 billion photos

1 per 2.3 people on earth

9.2 per US resident

DjangoCon 2008 7

35k photos/sec

>2m photos/min

DjangoCon 2008 8

Many thousand pages/sec

DjangoCon 2008 9

Scale nerd

DjangoCon 2008 10

Serious Language

DjangoCon 2008 11

Yahoo

FacebookMediawiki

Wordpress

DjangoCon 2008 12

Yahoo

FacebookMediawiki

Wordpress

DiggDelicious

DjangoCon 2008 13

Flamework

Serious Toolset

DjangoCon 2008 14

Flamework

Flint

Flinderbox

Flaux

Flag

Flink

Flotos

Flictionary

Flops

Fleng

DjangoCon 2008 15

Why hate Django?

DjangoCon 2008 16

What does he even know

about Django?

DjangoCon 2008 17

Pownce

DjangoCon 2008 18

A fucking blogging engine

DjangoCon 2008 19

Why all the hate?

DjangoCon 2008 20

DjangoCon 2008 21

DjangoCon 2008 22

DjangoCon 2008 23

DjangoCon 2008 24

An attack on several fronts

DjangoCon 2008 25

An attack on several fronts

The team

PythonFrameworks

DjangoCon 2008 26

Django itself

Performance

Scalability

Maintainability

DjangoCon 2008 27

The Team

DjangoCon 2008 28

Frameworks

DjangoCon 2008 29

Struts

DjangoCon 2008 30

Craig McClanahan

DjangoCon 2008 31

DjangoCon 2008 32

Exhibit A : Beard

DjangoCon 2008 33

But Struts is for suits!

DjangoCon 2008 34

The Hot Shit

DjangoCon 2008 35

DjangoCon 2008 36

Rails = Badass

DjangoCon 2008 37

Instead?

A boy band?

DjangoCon 2008 38

DjangoCoreThe Album

DjangoCon 2008 39

DjangoCon 2008 40

Simon “Stinky” Willison

Also, a wizard

DjangoCon 2008 41

Python

DjangoCon 2008 42

Trendy

Google!

DjangoCon 2008 43

But not that trendy

DjangoCon 2008 44

But not that trendy

It’s no ruby

DjangoCon 2008 45

But not that trendy

It’s no ruby

Or Haskell

DjangoCon 2008 46

But not that trendy

It’s no ruby

Or ErlangOr Haskell

DjangoCon 2008 47

But not that trendy

It’s no ruby

Or ErlangOr Scala

Or Haskell

DjangoCon 2008 48

Significant Whitespace

DjangoCon 2008 49

DjangoCon 2008 50

Salmon

DjangoCon 2008 51

Universe of marshy force. Field sense

shallows the hatchery saying Hello,. World!.

Hydro. Power spring sometimes; snowmelt

powers snowmelt always.

DjangoCon 2008 52

DjangoCon 2008 53

No quantum

superpositions

DjangoCon 2008 54

DjangoCon 2008 55

“-”.join(array)

DjangoCon 2008 56

Restarting the server?

WTF!?

DjangoCon 2008 57

WSGIReloadMechanism

DjangoCon 2008 58

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

DjangoCon 2008 59

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

[MOON L

ANGUAGE]

DjangoCon 2008 60

DjangoCon 2008 61

__import__()

from future import awesome

DjangoCon 2008 62

Basically, for hippies

OO languages

Scared of real

DjangoCon 2008 63

Frameworks

DjangoCon 2008 64

Flamework is a framework

But what does that mean?

DjangoCon 2008 65

Make common tasks:

faster

easier

error-free

DjangoCon 2008 66

Show a list of photos

Write an API method

Kill all humans

DjangoCon 2008 67

Front-tier frameworks

Act as glue

DjangoCon 2008 68

Data store

BusinessLogic

InteractionLogic

TemplatesRequest

Dispatcher

Users

OtherServices

Data Model

Framework

DjangoCon 2008 69

Great for getting started

Slows you down later?

What is it doing in there?

DjangoCon 2008 70

DjangoCon 2008 71

DjangoCon 2008 72

DjangoCon 2008 73

Fast

Flexible

Easy

Scalable

DjangoCon 2008 74

Large scale

is often not a good goal

DjangoCon 2008 75

Skyscrapers are special

DjangoCon 2008 76

Regular houses

Don’t need 10 story foundations

DjangoCon 2008 77

Just build!

DjangoCon 2008 78

DjangoCon 2008 79

DjangoCon 2008 80

DjangoCon 2008 81

Everything here is possible!

We care about easy

DjangoCon 2008 82

Large Scale

DjangoCon 2008 83

No multiple DB clusters

DjangoCon 2008 84

Manual partitioning

DjangoCon 2008 85

No multiple hosts per DB

DjangoCon 2008 86

Where do we read from?

DjangoCon 2008 87

How about now?

DjangoCon 2008 88

How about now ?

DjangoCon 2008 89

Read/write consistency

DjangoCon 2008 90

Read/write consistency

LAG!!1

DjangoCon 2008 91

Good for non-writing users

(logged out)

DjangoCon 2008 92

Non time-sensitive data

Feeds

Read-only APIs

DjangoCon 2008 93

DjangoCon 2008 94

Cool kids use

master/master pairs

DjangoCon 2008 95

Consistent read/write

1. Write to side A

2. Read from side B

3. Replication occurs

4. FAIL

DjangoCon 2008 96

Consistent read/write

1. Write to side A

2. Read from side A

3. ???

4. PROFIT!!

DjangoCon 2008 97

Then we can start to get fancy!

DjangoCon 2008 98

Where do we read/write?

DjangoCon 2008 99

Abstraction FTW

db_query($cluster_name, $sql)

DjangoCon 2008 100

No sharding

DjangoCon 2008 101

WTF is sharding?

All about books

DjangoCon 2008 102

Dewey Decimal

DjangoCon 2008 103

But it can’t do everything

DjangoCon 2008 104

Makes some things

‘impossible’

No shard walking

DjangoCon 2008 105

DjangoCon 2008 106

Django knows our models

It’s possible

DjangoCon 2008 107

If we accept constraints

DjangoCon 2008 108

No external sequences

DjangoCon 2008 109

Auto-incs can be bad

master/master

shards

DjangoCon 2008 110

No automatic denormalization

DjangoCon 2008 111

Counters would be easy!

DjangoCon 2008 112

And copied fields too

DjangoCon 2008 113

High

Performance

DjangoCon 2008 114

It’s slow!

DjangoCon 2008 115

DjangoCon 2008 116

DjangoCon 2008 117

There are limits

When being really silly

But they only apply

DjangoCon 2008 118

Sessions

DjangoCon 2008 119

OMG UR ON CRAK

DjangoCon 2008 120

Extra DB table

A read on every page

DjangoCon 2008 121

Lightweight = better

DjangoCon 2008 122

Signed cookies

DjangoCon 2008 123

No parallelization

DjangoCon 2008 124

Multiple cache-requests

DjangoCon 2008 125

Multiple multi-keyed reads

DjangoCon 2008 126

Slow HTTP requests while

we’re doing other stuff

DjangoCon 2008 127

Creates dumb SQL

DjangoCon 2008 128

foo.exclude(bar = true)

WHERE (NOT (bar = 1))

DjangoCon 2008 129

foo.exclude(bar = true)

WHERE bar != 1

DjangoCon 2008 130

foo.filter(bar = false)

WHERE bar = 0

Indexable!

DjangoCon 2008 131

Maintainability

DjangoCon 2008 132

Maintainability

Awesomeness

DjangoCon 2008 133

Verbose template syntax

<h1>{{ foo.bar }}</h1>

DjangoCon 2008 134

<h1>{{ foo.bar }}</h1>

<h1>{$foo.bar}</h1>

3 extra characters!

DjangoCon 2008 135

<h1>{{ foo.bar }}</h1>

<h1>{$foo.bar|e}</h1>

Well almost…

DjangoCon 2008 136

{if $edit_mode}woo

{/if}

{% if edit_mode %}woo

{% endif %}

9 extra!

DjangoCon 2008 137

Verbose template syntax

makes people cry

DjangoCon 2008 138

No query debugger

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'}]

DjangoCon 2008 140

>>> 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 141

Better, but not amazing

DjangoCon 2008 142

DjangoCon 2008 143

Page summary

DjangoCon 2008 144

Make it clickable…

DjangoCon 2008 145

EXPLAIN is AWESOME

DjangoCon 2008 146

And/or show the data

DjangoCon 2008 147

MySQL Query Profiler

Enough data to

choke a whale

DjangoCon 2008 148

Not smug enough

DjangoCon 2008 149

DjangoCon 2008 150

DjangoCon 2008 151

SELECT `app_userprofile`.`user_id`,`app_userprofile`.`account_status`,`app_userprofile`.`account_status_reason`,`app_userprofile`.`account_delete_type`,`app_userprofile`.`syndication_key`,`app_userprofile`.`blurb`,`app_userprofile`.`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_photo`,`app_userprofile`.`medium_photo`,`app_userprofile`.`large_photo`,`app_userprofile`.`orig_photo`,`app_userprofile`.`bday_month`,`app_userprofile`.`bday_day`,`app_userprofile`.`bday_year`,`app_userprofile`.`is_pro`,`app_userprofile`.`privacy_settings_id`,`app_userprofile`.`email_settings_id`,`app_userprofile`.`preference_settings_id`,`app_userprofile`.`ad_counter`,`app_userprofile`.`num_friends`,`app_userprofile`.`num_fans`,`app_userprofile`.`num_feeds`,`app_userprofile`.`num_blocked_fans`,`app_userprofile`.`num_friend_requests`,`app_userprofile`.`default_set_id`,`app_userprofile`.`invite_id`,`app_userprofile`.`invite_round`,`app_userprofile`.`avail_invites`,`app_userprofile`.`original_email` FROM `app_userprofile` WHERE (`app_userprofile`.`user_id` = 1)

Unreadable SQL

DjangoCon 2008 152

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

Unreadable SQL

DjangoCon 2008 153

SELECT * is fast!

Faster over the wire

Faster to parse

Easier to debug

DjangoCon 2008 154

SELECT `app_note`.`id`,`app_note`.`type`,`app_note`.`body`,`app_note`.`sender_id`,`app_note`.`date_sent`,`app_note`.`num_recipients`,`app_note`.`recipient_type`,`app_note`.`set_id`,`app_note`.`direct_to_id`,`app_note`.`media_file_id`,`app_note`.`url`,`app_note`.`url_inline`,`app_note`.`url_clicks`,`app_note`.`embed_id`,`app_note`.`event_id`,`app_note`.`is_direct`,`app_note`.`is_public`,`app_note`.`is_deleted`,`app_note`.`is_ad`,`app_note`.`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

Unreadable SQL

DjangoCon 2008 155

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

Unreadable SQL

DjangoCon 2008 156

Django makes me

scared of joins

DjangoCon 2008 157

JOINs are evil

Actually,

DjangoCon 2008 158

DjangoCon 2008 159

Low version number

DjangoCon 2008 160

DjangoCon 2008 161

DjangoCon 2008 162

Suspiciously small

Django: 105 klocs

Flamework: 260 klocs

DjangoCon 2008 163

Suspiciously small

Very long lines?

DjangoCon 2008 164

Can’t pluralize octopus

DjangoCon 2008 165

Commit all fields at once

DjangoCon 2008 166

Race conditions!

DjangoCon 2008 167

Dirty flags

DjangoCon 2008 168

Don’t make Malcolm cry

DjangoCon 2008 169

No simple way to inc/dec

DjangoCon 2008 170

Makes consistency hard!

UPDATE foo SET x=x+1

DjangoCon 2008 171

Character encoding

Input validation?

DjangoCon 2008 172

Character encoding

Input validation?

(Probably broken)

DjangoCon 2008 173

No mascot!?!

DjangoCon 2008 174

Echidna?

DjangoCon 2008 175

MAGICAL POWERS

DjangoCon 2008 176

No deployment system

DjangoCon 2008 177

Extending models

big enough

Tables are never

DjangoCon 2008 178

Model changes

manage.py reset appname

DjangoCon 2008 179

django-evolution

dmigrations

DjangoCon 2008 180

What’s django

done for you

lately?

thanks

(now go make it better)

DjangoCon 2008 182

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/

DjangoCon 2008 183

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/

DjangoCon 2008 184

these slides are online:

iamcal.com/talks