Hacker Newsnew | past | comments | ask | show | jobs | submit | ndanmand's commentslogin

We appreciate all your comments - Thank you!


Audio Visionary Music (imusic) | Aarhus, Denmark | Senior Full Stack Engineer (PHP/Laravel) | FULL-TIME, ONSITE or REMOTE

Audio Visionary Music is looking for a full-time software engineer who can become part of a team of 1-2 developers, based in Risskov, Aarhus, Denmark.

  [40 %] Full-stack web-development

  [20 %] Industrial automation

  [10 %] Continuous integration
  [30 %] Dev-ops
Technologies used on everyday basis include:

  * Languages: PHP / Python / HTML / Javascript / SQL

  * Frameworks: Eloquent / Laravel / Lumen
  * Orchestration: Vagrant

  * Platforms: Linux / Ubuntu / Raspberry Pi
As a person, you are serious, professional, reliable and well-considered. You are used to working at high pace and focusing on quality and scalability. We appreciate an exploratory mind that itself finds opportunities for efficiency improvements. You will have a great opportunity to influence how we build our solutions.

We have existed since 2005 and we operate the online store imusic.dk with sales of CD, LP, DVD, Blu-ray and books for the private sector. Since 2010, AVM has provided materials for libraries through public contracts, including the delivery of (all) books and nodes to all public libraries throughout Denmark.

Email me nick AT imusic DOT dk for more information or to pass along your resume/CV! Put Hacker News in the subject line so I don't miss your email.


> JupyterLab 1.0 will eventually replace the classic Jupyter Notebook. Throughout this transition, the same notebook document format will be supported by both the classic Notebook and JupyterLab.

Guess so :-)


Would you use this instead of Flask? Why/why not?

I'm planning on learning Flask, but would love any thoughts on this from experienced users.


The Django ORM and DRF autogenerated views are very good for quickly building CRUD APIs.

You get a lot of stuff in the box with Django:

* a very functional (if exceptionally complicated and hard-to-modify) admin UI

* a friendly ORM with good support for autogenerated DB schema migrations (better than SQLAlchemy for simple CRUD, but harder to go off the beaten track when you need to)

And building on that, DRF gives you

* Autogenerated CRUD API endpoints for your DB models

* Autogenerated serializers for your DB models, with field type validation

All of the above exists as plugins for Flask, but the feature set is less well integrated, and you need to figure out which plugin you want to include.

If you're trying to build a super-light microservice then Flask is probably worth looking at, though you can get Django quite light with a bit of work.

If you're trying to build a more complex system with nested API endpoints then DRF makes this harder for you (it's not possible in native DRF, but there's a plugin for it; I'm using this approach so it's not terrible).

And if you don't buy in to Django's ActiveRecord ORM approach (e.g. you want to do DDD and want to use a DataMapper style interface on your DB), then you need SQLAlchemy, and you can't use all the clever ORM mapping tools that Django/DRF brings, and so you may as well use Flask.


> exceptionally complicated and hard-to-modify

As an exceptionally mediocre programmer who routinely creates extensive admin customisations I dispute this.

Seriously. Where does this meme come from? The admin is remarkably easy to customize for the most part. It's biggest flaws are incomplete documentation and a few monolithic methods/templates mostly around changelists.


At least part of the problem is that it looks so, so weird, and it's really tightly bound to models. This is like the most customized admin i've made and it's still pretty simple, but it sure doesn't feel that easy to reason about when you look at it (it's an admin page that lets you link a specific admin-page input to a model, then display it in a list that you can add to):

  from django.contrib import admin
  from django.forms import Textarea
  from .models import *
  
  # Register your models here.
  
  class BotTextInline(admin.StackedInline):
	model = BotReplyContent
	extra = 1
	fieldsets = [
		(None, {'fields': ('message_type', 'text', ('template_text', 'example_text',), 'order',)}),
		('Actions and inputs', {'classes': ('collapse,'), 'fields': ('action_type', 'input_type',)})
	]
	# readonly_fields = ['input_type_ptr']

  class BotReplyAdmin(admin.ModelAdmin):
	fieldsets = [
		(None,               {'fields': ('state', 'intent', 'context', 'description', 'next_state',)}),
	]
	formfield_overrides = {
		models.CharField: {'widget': Textarea()}
	}

        list_display = ('state', 'intent', 'context', 'description',)
	save_as = True # lets you save the content on screen as a new id
	inlines = [BotTextInline]

  admin.site.register(BotReply, BotReplyAdmin)
```


This is a trivial amount of customization.

Yes, you have to know what the class fields do. But you just saved yourself days of having to make your own CRUD view from scratch.


Totally trivial. And yet, I still can barely parse what's going on in there.


But proportional to the docs and total customizability and sheer mass of code and functionality that happens.

You're getting free authentication for an admin + free UI + a fully customizable list view + customizable create/update view + delete with a useful confirmation dialog + trivial field search + trivial filters of all sorts include date drill-downs.

It's a huge amount of things to do by hand.


> Seriously. Where does this meme come from? The admin is remarkably easy to customize for the most part.

I haven't found this myself to be honest. Usually you have to trawl through several stackoverflow posts and evaluate several different ways to do things you would expect to be simple. I don't have many examples in mind right now except showing image thumbnails, dealing with base64 image uploads and automatically resizing image uploads were way more cumbersome to implement than I would have expected. Most solutions we arrived at felt hacky for tasks you would think would be built in by now but I don't have a better framework in mind for CRUD work.

The default admin interface is really good though as well as the database migration tooling.


My experience report is based on operating a production API with about 30 DB models, not incredibly complex, but with somewhat non-standard requirements like multi-tenancy. This opinion is shared by the developers on my team as well, if that's worth anything in addition.

I've found the easy stuff to be very easy to do in the Django admin, and every time I've tried to do something off the beaten track, it's taken me days instead of the hours or minutes it feels like it should do.

Any of these would be good examples of things that feel like they should be easy, but aren't:

* Adding a link to a custom page onto the frontpage of the admin, ideally under a custom "App" header. * Creating a read-only view onto related objects (impossible in some situations, depending on the direction of the FKey relationship, annoying in others). * Presenting a form for creating nested one-to-one objects along with a parent.

I'm sure that if you routinely make modifications to the Django Admin it gets easier; the second time on any of these items is 10-100 times quicker for me.

I'd blame the poor code discoverability of the template-based system, poor documentation, and lack of a broad corpus of examples for making this harder than it could be.


> * Adding a link to a custom page onto the frontpage of the admin, ideally under a custom "App" header.

This one's simple—just override base_site.html.

As for the others, I'm not really sure I understand what creating a read-only view / form for nested 1-1 objects means, but I'm sure there's a decent, not so crazy solution out there.


> just override base_site.html

And if your changes break in a future version of Django, how exactly is anyone going to be able to debug that? Having to override admin templates that are at best only semi-documented is incredibly hacky.


With any Django app, you’re going to pin your requirements to a specific Django version as a matter of course. If the change is broken in a future Django version, you’d need to update it like you would need with any other breaking change.

But, if experience is any guide, despite lots of tinkering with the admin, Django has yet to break anything I’ve customized in the admin (I’ve been using Django since 0.96). YMMV.


Django has the best deprecation policy of any framework I've seen. Breaking changes are always documented and given fair advance for changes.

In many years of working with Django I have not really seen a significant breaking change in the admin unless you override private methods.


If you are spending "days" in some Django Admin modifications, you are definitely doing it wrong. At that point you should have rolled out your own admin just like any other feature. Clearly the builtin admin is working against you rather than with you if it takes that long to do what you need to get done.

The Django admin is meant for development. Ofc, it can be used by non-devs and I've seen a multimillion dollar business that mainly uses the builtin admin to manage their main product. However, there's always that point when customising something that is fundamentally different than what your needs are doesn't make sense.


It would take considerably longer than a day or two to build a replacement admin of comparable functionality, so I don't agree with your assessment.


> The Django admin is meant for development.

I dispute this. And the community is pretty split on it too.


I recently overrode the admin widget for ArrayField to make it possible to add and delete entries individually rather than entering the whole array as a big comma-separated block. I got it working but it felt pretty hackish. Maybe there was a better way but I had trouble finding good resources on what I wanted to do.


Surely that's Django forms and widgets? Nothing there is admin-specific.


Have had the same hacky feeling trying to do anything in the admin beyond using the standard widgets.


OTOH, using Django + DRF, you will be fighting the framework if you want to do anything besides serialize and deserialize models from your database. We use DRF where I'm at, and I often wish we didn't.


If you're fighting the framework, you're doing it wrong.

It is trivial to use serializers for non-ORM stuff. It is trivial to not use serializers at all. It is trivial to plug your own auth and permissions.


I'm a heavy Django user, and have used DRF occasionally. I find Django extremely pluggable and extensible, but I needed to write an API with DRF that didn't map cleanly onto the database models, and that was pretty cumbersome.

DRF doesn't like it when you do things that don't map to the models, and the documentation is pretty bad. I had to read the source in the end to figure out how to do what I wanted, and I got the sense that I was lucky it was doable.

If your database models map to your CRUD endpoints, though, everything is super easy.


I use a lot of custom Serializers (not tied to any Model), and lots of SerializerMethodFields to selectively override generated ModelSerializer fields; this can get you quite far.

I agree with your point that the further afield you go, the less you gain from the framework, though.


That's what I ended up doing, if I recall correctly, but the docs on this were pretty much non existent.


> a very functional (if exceptionally complicated and hard-to-modify) admin UI

The flexibility of the admin UI has improved dramatically in the last few releases. It's still relatively complicated, but it now has way more places to override behavior.


> last few releases

By "last few" you mean "since about Django 1.4" in 2012


I normally recommend that people learn Flask if they really want to learn. Flask is simple and you have to do more yourself, which means you really get to understand how each component works. Django will get you set up faster, and has a lot of third-party middleware that you can use off-the-shelf. If you're learning, some of it will seem like magic and it'll take longer to figure out what does what.

TL;DR - Flask for education and simple projects. Django for creating CRUD apps where you just need it to work.

Shameless plug -- I wrote this comparison[0] which shows how "Hello, World" is written in Flask and Django, and goes over some pros and cons of each in more detail. The editors added the "Why Flask might be better" part to the title, which caused most of the discussion about the post to turn into a flame war, but I tried to be as objective as possible (although I do prefer Flask -- another shameless plug for my book[1] Flask by Example).

[0] https://www.codementor.io/garethdwyer/flask-vs-django-why-fl...

[1] https://www.packtpub.com/web-development/flask-example


I disagree, I don't think Flask is better for learning than Django, It is true that many components are already built inside django but the complexity is not really hidden, the developers still need to understand how the framework works.

For sure you can create a basic view with a ModelSerializer by hiding all the complexity, but very often it won't be enough to build what you want to build, and therefore you will have to search trough the documentation how things works.

In my opinion both Flask and Django are good for learning purposes, but Flask requires the user to handle more complexity than Django, which is not always the best thing if you want to learn


It definitely boils down to personal preference in the end. I always hated trying to wrap my head around solutions before understanding the problem.

By using Flask first, you also end up thinking "wow, every time I build a flask app I go through these same repetitive steps. Would be nice if they were automated". Then you find they are automated in Django.

If you learn the solution first, it seems irritating and sometimes you never understand the problem that it's solving.


I think one of the big reasons to try Flask first is to learn what magic is under the hood. If you start with Django, you're asked to build your MTV in a very specific way. That way Django can give you stuff like XSS/CSRF protection.

If you don't know what magic Django is doing for you, it feels restrictive to do stuff the Django way.


I don't mind Flask for writing projects, but coming into an old Flask project where the dev is no longer around isn't as fun.

Mostly because the structure can be absolutely any shape, the last one I went onto used the Django structure, but it may as well have just been Django.


Lots of advice on here but I'll try to add something useful.

For a project, you can't blanket say "use flask" or "use django with DRF" without a little more context. They're not even that comparable in a way.

In terms of learning, if you already know how to code then just take a quick look at Flask. The core library is so small you can get the gist of it in less than an hour; there's nothing to lose. That's the great thing about Flask. After that you'll be fairly well on your own. There are libraries for most everything you need to do but you'll have to hack on them yourself.

If you have no dev experience then get a page running with flask just to get you excited about development...and then maybe stop there. You have to weigh up too many things and figure out how to get them all working nicely together to do more complex things. Django can guide you through this process better with the decisions made for you.

DRF is a really nice library. In fact, as someone sworn off django from the bad old (v0.9) days, I almost went back because DRF is so nice, and that was back when it was DRF v1. Tom Christie is an brilliant developer and if you're building an api, DRF is best of breed.


If you already use Django and want to expose an API, DRF is a natural choice. Flask is more simple to use, if you have to do simple things. If you need models, access to a database and you don't want to pull third party libraries for things that are normally part of a complete framework, I usually suggest to use Django rather then Flask. This said, Flask remains a nice, light framework and I personally use it for a few services.


I recently went down this path, trying to build something akin to DRF but using Flask. I'd never used Flask before, but had some Django experience and was no stranger to Python or web frameworks in general. With Flask there are a lot of choices you need to research/make around which libraries to use, and how to get them all playing nice together. I obviously ended up using SQLAlchemy but decided to spend some time writing a customized integration between Flask-RESTful and Flask-Marshmallow for the views/serialization layer.

Certainly it took me a bit longer to get up and running compared to if I'd just used DRF, but on the plus side, I feel like I have much stronger grasp on how everything works now, whereas Django still has a ton of surface area that feels a bit like magic to me. If you're interested, the repo is open sourced under MIT here[0].

[0] https://github.com/briancappello/flask-react-spa


I went the other way around and came up with https://github.com/shosca/django-rest-witchcraft as the project is already using django+sqlalchemy and I needed to do api's on existing things.


Nice! How do you find SQLAlchemy integrates with Django overall? (Can you use its models with the admin?)


I recently used it to implement a BFF (backend for front-end) for a mobile app on a "legacy' system. I spent about 3 normal, non-crunch days to code and write ~20 endpoints (most with 2-4 verbs) w/validation and tests that spanned over 25 models. Also had about a dozen context-sensitive permissions to account for as well in a DRY manner (eg: user must be of type X and have plan Y or return a 403).

Normally not a "big" framework kinda dev but I'm quite proud of how clean and well organized the resulting code was. Adding additional endpoints in the future can be done in minutes or hours at most, since all the pieces are now there.

I don't have any experience beyond that though, and I've never started a brand new product from the ground up with it, but it made my life super easy last week.


Cconsider also looking at Pyramid Web Framework. Provides nicer defaults and does not rely on threadlocals and globals. By defualt you will also get sqlalchemy and jinja2 templating out-of-the-box. It also handles building REST apps nicely.

Django on other hand will give you monolithic solution for the price of less flexibility than flask/pyramid.

If you just want to handle REST views - I think falcon framework is nice (speed wise) - haven't used it myself yet though.


Pyramid also has some REST specific addons available for streamlining development - eg Cornice etc


I looked into Pyramid but couldn't find an active admin project. Is there one that people tend to use?


You mean like auto-generated admin panel? I would look for something directly related with sqlalchemy - not pyramid. I don't use such panels so I can't give good advice here.


If your interested in flask and api's have a look at https://github.com/zalando/connexion, but personally I'm more a bottle kind of guy.


Flask gets you up and running extremely quickly, but as soon as you need to do anything moderately complex you need a heap of extra packages or code. Django comes with the kitchen sink included, but has a much steeper learning curve to understand how all of the parts for together (e.g. there may be 3 or 4 files you need to edit to make a change to something).

I use both, for very different applications.

There are also some packages for Django that make it more flask-like (e.g. importd) but I've never used them in real life.


Flask is great, but it's bring-your-own-*. Meaning that you need to pull in everything custom and, in many cases, that means you re-implement something like django in a different way. Each has their own merits, and being a Python developer knowing both is often good. Granted I see a lot more job postings for Django than Flask, for what it's worth.


Flask is better if you want to do more of the work yourself.


Depends on what you want to do. Django’s ORM lets you do many things which would take awhile to reimplement in Flask.


That's definitely wrong. If you're using Flask and need an ORM you'll use sqlalchemy - which, in my experience, is the best ORM in existence (for any language).


How is it better than Django's ORM in your experience?

I used sqlalchemy a little bit in 2012 and didn't like the feel of it (too much configuration over convention, I felt), and since then I've been using Django's ORM even in non-Django projects (which is great both because of how good Django's ORM is and because eventually I always encounter the for need a nice admin interface and solve it in 10 minutes with Django's admin panel generator).


I'm not sure why people have been downvoting you - it's really not an unreasonable question (I've upvoted to try to counter that). To be honest it's been so long since I used the django ORM so my initial assessment my no longer be so true.

SQLA handles pretty much everything. It's built in really clean layers with the Core implementing all of the sql abstractions. If you can write it in sql, you can write it in SQLA. The ORM is just another abstraction which sits on top of that. This architecture makes it really extensible and flexible. We've bent Alembic (the migration tool) to our will and it's amazingly easy to hack on. For me it's one of the greatest pythonic tools.

One of the deeper more subtle issues is that if you architect using something like the django orm, it's assumed to be there and all the libraries / plugins etc will have a structure that's insidiously tied to the underlying data loader (this is a django problem, not a django orm one). Depending on what you're doing that might be ok, but for some projects that's going to bite you over the lifetime of the project.


Thanks.

I always thought every project should have a few well thought out and relevant "invariants" - assumptions that it's easier to rewrite than change, that the whole architecture is built around. They can be a data structure, a library, a way data flow is structured, whatever, as long as they make the rest of the architecture naturally fall into place around them.

On database-heavy projects like CRUD web-apps it makes a lot of sense for the ORM to be such an invariant. And I've never hit the point where I was sad to have my ORM so entangled with my code. So it's really hard for me to get this perspective, although I hear it so much around me.

I guess my takeaway from this conversation would be to study the SQLA architecture as a shining example of correct layers of abstraction, but keep using Django ORM in practice until I encounter a situation where I wish I wasn't.

How did you "bend the migration tool to your will"? What did you need it to do that it didn't do natively? What other things did you need to do that an opinionated generic ORM like Django's considered "against the grain"?


Agree with you, and it totally depends on how the project is going to unfold.

Alembic works by introspecting the db (using sqla) and then creating a script, in sqla, that migrates the current db to match the model defined in code. You can hook in to change that process. In our case, we wanted to create a fully automated Choice type using native python enums. We then added a hook to alembic so it could detect the inconsistency in between the constraints in the db and the code and update them accordingly. The whole thing is about 50 lines. There was a bit to learn, but with sqla / alembic you just slowly start peeling back the layers. Ironically that's all probably something that django has covered!


sqlalchemy the reason Im in love with python!

edit: To make this a more-effort post see https://www.sqlalchemy.org/features.html and http://www.aosabook.org/en/sqlalchemy.html for reasons.


Checkout Apistar then and see Flask's capabilities. https://github.com/encode/apistar


Having used apistar in production for a month now, I sort of wish I went with Flask...


What's the catch?


I've used apistar quite extensively in two different projects (one launched) and so far I like it.

One disadvantage is you can't use wsgi middleware, but after rewriting our middleware to components they ended up being much neater. I'm a fan of the bottom up approach where you define the components you want in a route. We have some routes which just returns the database query and with a custom renderer it will get rendered in the json format we expect


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: