DjangoCon US 2017 – Django vs Flask by David

(gentle guitar music) – So if you're having trouble viewing the slides particularly on this side of the room, I actually have a link to them It's bit

ly/djangocon-flask so you can check it out on your computer and follow along and jump ahead if you want to cheat So yeah, as Brian said, hi, I'm DB I'm a freelance web developer I'm a corporate trainer I do lots of stuff on the side, so if you or your company like what I have to say or are interested in having me implement some Django or Flask for you, let me know

So I'm here to talk about Python and web dev And if you're here at DjangoCon, then you're already familiar with Django, of course But there's lots of other Python web dev frameworks out there So Django is actually influenced by several earlier frameworks like Zope and Plone, and in turn it has inspired lots of other frameworks that came after it, like Pyramid, TurboGears, CherryPy, Bottle, and Web2py But the one that I'm here to talk about is called Flask

Now Flask is a micro-framework that has some surprising beginnings It actually started as an April Fool's joke, if you can believe it The author of this framework had written two other frameworks called Werkzeug, which is like a server framework, and Jinja2, which is a templating library And he figured it'd be kind of fun to take these libraries, put them together in a zip file, and then write this denied framework that when you ran it, it would automatically just unzip these libraries onto your computer and run them, and thought everyone would just laugh

And instead, everyone said, "This is fantastic! "We need to actually use this in production!" (audience laughs) So he turned it into an actual production ready framework that has actually gotten surprisingly popular If you look on GitHub Today, you will see that if you list all the Python repositories, Django and Flask are both up there, and Flask actually has more stars than Django does So if that's your measure of popularity, then Flask is more popular So you might be asking yourself, "Why is Flask so popular? "Is it actually better than Django?" And the answer, as you might imagine is "It depends" Django is large, Flask is small

Both of them are good You know, we're a friendly community and we love each other So let me give you some examples to introduce what Flask is and how to use it I'm assuming you have some familiarity with Django, but that you know little to nothing about Flask So, where do we start with programming? We always start with Hello World

Here is the Hello World application in Flask As you can see, it is literally five lines of code And you run it by calling, "flask run" and setting an environment variable to let the Flask command line script know where to find your application So in this case, I've taken these five lines of code and put it in a file called hellopy

So I just say, "Flask app equals hellopy flask run" And that will start a local development server on port 5000, and if you visit the root of that website, you'll see the string Hello World in your browser It it really that easy By contrast, if you want to do Hello World in Django, you start by installing Django, and then you do, "django-admin startproject project

" You go into your project, you make your Hello app, which then of course you have to put that into the settingspy Then you write your hello/view, which requires importing this HttpResponse thing and returning it Then you have to deal with urlspy, which means writing regular expression, which is always a pain, especially for someone who is new to programming and doesn't necessarily know how to do regular expressions

So I've actually found when talking with people who are new to web development and Python, that Django is more intimidating to beginners than Flask is Django has a steeper learning curve because you have to go over settings and regular expressions You have to understand the concepts of projects versus applications Flask is much simpler to get started You can actually have your entire project in a single file, and that works really well

So, by that account, Flask wins out with the simplicity factor for getting started But, projects are generally more complicated than Hello World Typically you want to store some data in a database, modify it, and render that data on the front end So how do you do data modeling? Well let's start with Django this time Well in Django, we're gonna use the Django ORM

So you do, "from djangodb import models" And here I'm defining a very basic blog post model This is code that you've probably seen before To manipulate the data, you just create an instance of it, assign information on properties, and do object

save And then you can query the database by doing, "BlogPostobjects," And you can do filters, and you can do selects and all sorts of standard things that you can do with database querying So how do you do the same sort of thing in Flask? Well the answer is, "You don't" So Flask actually doesn't have data models

Now you're looking at this and you're wondering, "How can that be? "How can a web framework not have a data model? "How can a web framework that's apparently "more popular than Django, not have a data model?" Well the answer is that Flask has a very different perspective and ideology from Django Django bundles everything all together, and Flask is much more modular So here's an example of how you might handle data modeling in Django versus Flask You can see that the Django ORM is built into Django itself You install Django, and you've got it

Flask doesn't have that, but Flask has connections to other Python modules in the Python package index that will do data modeling for you For example, the SQLAlchemy ORM is a very popular one If you want to do non-relational databases with MongoDB, you can use MongoEngine There's a small framework called Peewee that's been getting some attention lately So the idea is that Flask is very, very minimalist

It has almost nothing in there It has only the bare necessities for when you need in order to do a simple static website, essentially It includes templating, URL routing, error handling, and a debugger That is all However, it is designed to be incredibly extensible, so that you can plug and play, and choose which components that you want to plug into your website and make it work exactly the way that you want

So, let me give you an example that show you how you might do data modeling using SQLAlchemy and Flask So there's an extension called Flask-SQLAlchemy, which is designed to cleanly integrate these two different modules So you would just install that, and that installs SQLAlchemy itself as a dependency And then you do some basic set up to configure it So I'm gonna import that extension, and I'm going to configure it onto my Flask application

And as you can see, the Flask application also has this config object where you can set information that your application or extensions can read and use So in this case, I might say that I want my database to be a sqlite database that uses the testdb file under the temp directory Whatever

The thing that's really important here is that you notice that you're importing the SQLAlchemy class, and you're creating a variable called, "db," that you get by wrapping your application with SQLAlchemy So now that you have this "db" object, you can do some very familiar things with it So here I'm defining a data module, a blog post data model, and you can see that it looks very familiar to the same sort of thing that you would do with the Django ORM In fact, I'll take the previous example and I'll put it on the same slide so that you can compare and contrast They're not identical, but they're very similar to each other

And if you've used the Django ORM, you can use SQLAlchemy in almost the same way You can also manipulate data in very similar fashions So you can create an instance of a blog post, an instance of a blog post class, assign information to it, and then instead of calling save on it, you have to add it to the database session and commit the session It's the same basic concept

SQLAlchemy is just making you sort of be a little bit more explicit with how this database interaction works And you can query data in the same way So you do query instead of objects, and you can do

filter or filter_by And there's a lot of same basic things that you can do in Django, and you can do the same sort of thing in SQLAlchemy In fact, I'm of the opinion that SQLAlchemy is a more powerful object relation mapper than Django ORM But that's another topic for another time

So (DB laughs) (audience laughs) So to talk about data models here on a higher level, Django's data models are easier to get started because they're built-in So you don't need to import and install anything else to get started

However, Flask allows you more flexibility to choose whatever you want to use Django assumes that you're gonna use a relational database Flask, you can use whatever you want You can use Mongo You can use Google App Engine's data store

You can use whatever, it doesn't matter But of course the more options you have, the more flexibility you have, the more chance you have to screw something up So you know, it's a trade off there Let's keep going Most web applications have users, and they also have an admin to be able to view information in your database and modify it

So how do these compare? Can you do this sort of thing with Flask? Well with Django, we have your familiar, "djangocontribauth" It's built in, it's easy I'm sure you're all rather familiar with it

If you need extra information for users, you can swap out the user model It's a little complicated You can also make a UserProfile to attach to it That's also a little complicated, but it works pretty well With the admin, you have, "django

contribadmin" Also built-in and easy, very customizable, and there's a lot of documentation out there With a fine-grained permission system so that different admin users can get access to different objects to administer So how do we do it in Flask? Well as you might imagine, you don't have users built-in because you don't even have a data model built-in

But, there is a very popular Flask extension called Flask-Login, which is generic, and works with just about any data model, including SQLAlchemy if you'd like So here's an example of how we might do that I'm going to define a user class, and you can see I'm importing this UserMixin from Flask-Login That gives it a couple of extra little superpowers, so that we have some standard usage that you can use across your framework, regardless of whether you're using SQLAlchemy or Mongo or whatever So for example, in my route, I might say, "If current_user

is_anonymous" Now "current_user" is something that's provided by Flask-Login It's a pointer, basically, to whatever user is currently logged in And the "is_anonymous" thing is provided by that UserMixin that I showed you earlier So here's a simple view where I'm saying, "If you're anonymous, just render the splash page, "otherwise show the user homepage

" Flask-Login will also give you a "login_required" decorator, which you've probably seen from Django as well So it's just a decorator that you apply to your view If the user tries to access the view and they're not logged in, they'll get a "403 Forbidden" exception Again, very similar to Django, but the idea is you build this piece by piece With user permissions, you can also use the, "Flask-Principal" extension that has a very similar fine-grained permissioning system, the same way that Django

contrib off models do So the idea is if you don't want a permissioning system, you don't need to have it Django users have that built-in by default, and you have to sort of deal with it whether you want it or not With Flask, you can decide if you want to add that in or not And with the admin, as you might expect, there is a "Flask-Admin" extension as well

So you want to use that You install it, you set it up, and you decide which theme you want to use It has a couple of themes built-in based on Bootstrap, or you can write your own It works with several database backends, including SQLAlchemy, and Mongo, and Peewee And it's designed to work with or without any user extension that you want

So it's very common to have it work with Flask-Login and Flask-Principal, but it's not required Here's some screenshots of how it looks Here's the list view so you can see all of your users Here's how you edit a user As you can see, it's all standard Bootstrap

So it's pretty familiar and it's pretty powerful Now there's a lot of different extensions that I've just gone over, and having a user and admin system is pretty standard, so there's actually an extension called Flask-Security, which all it does is it takes about five or six different Flask extensions and bundles them all together into one package, so that they're already designed to hook up together properly So you can just install this one extension, and BAM, you've got your users, your permissions, your admin, it's all there It's great And of course, it works with SQLAlchemy, MongoEngine, or Peewee

So you've got a lot of flexibility here So again, Django has a user framework and admin built-in, and they work very well They're not as flexible as personally I would like, but for a lot of people they work great Flask requires a lot of different extensions working together in concert, which makes for a steeper learning curve, but it means that you can define your user model and your permissioning system to work exactly the way that you want So it's basically a question of do you want off the shelf, or do you want extensive customization? There's also the idea of reusable apps

So Django has got this nailed with the whole Django apps system, that you have to have an app every time you create your project All code related to one concept lives in one place, like, for example, you might have all the registration logic in one place How does that compare? So with Django, you install your thing and you get it set up in the Installed Apps list in the settings You have the Django Packages website available, which is fantastic and shows you a lot of good information about the packages available But, it's a little hard to figure out which packages you actually want, which ones are maintained, which ones are high quality, and so on

And of course, if you're writing your own applications, it's very tempting to just stick everything into one app rather than organizing it into several It's sort of complicated to figure out how you want to move all those pieces around By contrast, Flask has something called blueprints, which are not quite the same thing, but they're pretty similar It's a way of organizing the views in you application so that you can again, group logic together into similar places But it doesn't require that you move models into different places

It doesn't require anything about migrations in different places It's basically just views, so it's much smaller and much more lightweight, which might be a good thing or a bad thing, depending on how you look at it It's also a very familiar syntax So let me go back to our basic Hello World that we had before, and I will take this application and I'll transform it into a blueprint just like this You can see the only things I had to change was turn the app variable into a blueprint variable

And I can still do the same basic route decorator on top And now once I have this, "hello underscore bp Blueprint," I can attach it to an existing application Just by importing it from the file where I have it defined, and I can call, "appregister_blueprint" of the blueprint that I've defined So it makes it much easier to take an application that was originally defined as one monolithic application and separate it out into several different blueprints, although you might do the same sort of thing with Django apps

So, to compare, Django apps are more comprehensive There's a lot more of them out there, especially if you check the Django Packages website But they're are also more complex, and sometimes it's hard to refactor your own application into Django apps By contrast, Flask blueprints are simpler, and they're easier to integrate with a project, but maybe they don't provide the power you're looking for Again, it's sort of a subjective thing

Another thing that a lot of websites need is APIs They're increasingly common for web applications, and they have different user patterns compared to HTML webpages So, how do these two compare? Well when you're dealing with Django, you want to use Django REST framework It's great, I'm sure you've all heard tons and tons of praise from this framework over the past few days It's multi-layered abstractions, so you can choose which layer you want to go with

It has tons of documentation, and it works great So what about with Flask? Well as you might imagine, you wanna use multiple different extensions working together to provide the experience that you're looking for With Django REST framework, typically the thing that sort of forms the core of how your API is structured is the serializer And in Flask, you would probably want to use the "Marshmallow" module, which is, as you might imagine, a serializer framework And the ecosystem has integrations with Flask, with SQLAlchemy, with MongoEngine, with a whole bunch of other things

So no matter what sort of structure you've decided for your web app, Marshmallow will work properly with it So, let me give you an example This is a fair amount of code, but this is an application written in Flask that returns a JSON based API endpoint, to return information about the currently logged in user Now, I'll annotate this a little bit You can see at the start, I am importing a whole bunch of stuff and then I'm going to initialize the Flask Marshmallow extension and save it into a variable called, "ma

" Then I'm going to define my schema, which is basically the serializer Django REST framework uses the word, "serializer," Marshmallow uses the word, "schema" It's the same basic thing And you can see I'm telling it to just find the fields defined on the user model, and exclude the password field because we don't want that being displayed on our API And then in the actual API view, I can just say, "Initialize this user schema, "and take the current user and output it as JSON

" And I also have the login_required decorator that I talked about earlier, which will make sure that you can only access this API endpoint if you are currently logged in So this is one page You know this maybe 15 lines of code, and we have a basic API set up in such a way that you can understand every single piece of the puzzle of how it's put together So, Django versus Flask when it come to APIs? Django REST framework is amazing I really wish that Flask had something that was as well put together and as clean, and as abstracted as Django REST framework

We don't have that yet Maybe someone will put that together the same way that people did that for Flask-Security But as it is, you can still use all the extensions that you want to put together something just as powerful as DRF, if not more so And you have more flexibility as well, because you're not constrained to the constraints that Django puts upon you You can use a non-relational database if you want to

You can use any sort of different components that you want to mix into your application to make it taste exactly the way that you want So, the question you might be asking yourself is, "Which one do I choose?" and of course it's up to you, it depends on the project, but let me give you a couple of brief bullet points so that you have an idea of which to go for You generally wanna choose Django when you're happy with all the choices that Django makes for you So I've been talking about how Django restricts you to using a relational database Maybe you like using a relational database

If that's the case, go for it Django makes you use Django templates, although that's changed recently You can swap out different templating systems But generally, you want to go with the things that Django provides for you The more that you do that, the happier you'll be

If you're not doing anything too unusual, Django will work great for you because the more that you try to fight the framework, the more pain you'll experience And also, Django sort of sets up a whole bunch of different things for you You can peek under the covers and you can learn how the ORM works, and how the templating system works, and how all the different pieces fit together But you don't necessarily have to By contrast, you might want to choose Flask when you disagree with one of Django's choices and you want to do things differently

If you want to use SQLAlchemy instead of the Django ORM, for example Or if you have unusual requirements, like using a non-relational database, or doing something else that seems a little bit odd or unusual for a web framework Django will fight you a little bit on this Flask will say, "Yeah, do what you want, great" Or it's great to use Flask when you're doing a hobby as a side project

And maybe you're less concerned with having a working project and more concerned with understanding all the different layers and how they work together It's great for really making you learn how all the pieces fit together, and it'll make you a better programmer by having that understanding So I'm about out of time, but that's all I had to say Does anyone have any questions? I only have a little bit of time to take questions And I will also say, I'm sure there are a lot of people here with opinions, so I'm going to be out in the lobby

(audience laughs) to host an argument session after this talk – [Programmer] So I built a Flask application last weekend, and coming from an object-oriented world, I was like, "All right, I could build this in one file, "but I really wanna split my router out, "and I wanna split my models out, "and I want to have my apppy

" – Mm-hmm – [Programmer] And I really couldn't find anywhere on the web that actually tells you how to do that There's lot of things that say, "Here's how you do the single page" And there's lot of things that sort of say the really complex sort of, like, "Here's how you put all the things together" There's nothing that really says, "Here's how you put your router in just a different file

" I managed to get it to work, but I feel like I was doing something wrong Do you have a Like, how do you actually separate the concerns? – So, Flask's greatest strength is it's flexibility, and that is also it's greatest weakness

So, you can separate your file in many different ways, into, you know, whatever names you want In terms of the actual functionality, the actual step by step way of doing that, you would just take your code, copy-paste it into a different file, and then in your main file, you import what you copy-pasted from someplace else So it's just using Python's import system It's nothing specific to Flask In terms of which files you pull those out into, how you name them, where you move your code around, that is a subjective thing

And that's gonna depend on what you're interested in There are a couple of tutorials out there, and you can follow them if you want, but ultimately it's up to you – [Female Audience Member] Thanks for the talk Could you go back to your, "Choose Django when" slide? – Sure – [Female Audience Member] I just had a question about that I'm trying to keep my question in the form of a question Could you please say more about your, "Not doing anything unusual," because I feel like that's a little bit leading

You might not start out doing something unusual, but as you grow in scale and try new things, you might end up doing something unusual So can you just say a little bit more about what you had in mind there? – That is very true I have to admit, I don't have a specific use-case in mind for what I'm thinking of, but there are people who, for example, might want to use a web framework in a way that a web framework was never really designed to be used for Like maybe using it to do a Task Queue application, which I've seen people try to do I've seen people try to use a web framework in order to just have a task runner on the command line

So, sort of like you might have rake or managepy, and people will try to fit some logic into a view or something like that All these are probably bad ideas, and Django will try to steer you away from that Flask will say, "Yeah, this is a very small, "very flexible framework, "you can use me the way that you want" So again it's a question of, do you want your framework pushing you in certain directions? Or do you want your framework to say, "Yeah, you know, I didn't think that "you wanted to do it that way, "but if that's really the way you want to do it, "go for it

" So I guess it really depends on a specific use-case I'm sorry I don't have anything more specific to say about that – Unfortunately we've run out of time for questions The beat down can continue in the hallway track (audience laughs) Until then, let's have a big round for David "DB" Baumgold