
Django REST framework 3.5 - cdnsteve
http://www.django-rest-framework.org/topics/3.5-announcement/
======
alexbecker
I like DRF, but I think its allow-by-default mentality is a security risk. If
you use it, keep in mind that:

* ModelViewSet is read/write, you should use the more verbose ReadOnlyModelViewSet until you know you want to allow writing.

* Fields specified in the "fields" member are read/write by default. You have to explicitly declare the field on the ViewSet and pass "readonly=true" to make it read-only. This is especially dangerous for ForeignKey fields, which can be used to change object ownership if you aren't careful.

When I was responsible for a DRF-based API I wrote some custom Fields and
ViewSets to use safer defaults, and I recommend others do the same.

~~~
dopeboy
If you want to get even more granular, I would suggest using the mixins. I
almost never use the broad viewsets anymore.

Example:

    
    
      class FooViewset(  
              mixins.CreateModelMixin,  
              mixins.ListModelMixin,  
              mixins.DestroyModelMixin,  
              mixins.RetrieveModelMixin,  
              viewsets.GenericViewSet)
    

Subtract as necessary.

~~~
alexbecker
This is a good way to control what methods are allowed on the ViewSet, but
still doesn't address the problem of fields being writable by default when the
ViewSet allows writing.

~~~
chc
This seems like the expected behavior. If allowing for writing didn't actually
allow you to write anything, that would be pretty strange, wouldn't it? Or do
I misunderstand?

~~~
alexbecker
You may want to expose some fields that you don't allow changing, such as what
account owns the resource. When fields are writable by default, it is easy for
someone to miss that they've made a field writable when they just meant to
expose it for reading.

~~~
Kpourdeilami
I think it's better to define field specific read/write permissions through
the serializers. In the serializer's Meta class, you can define a
readonly_fields tuple containing the string names of the read only fields

~~~
qnrq
You can also route only read-only methods in urls.py, for example via:

    
    
        url(
            r'path/$',
            TheModelViewSetView.as_view({"get": "list"}),
            name="thename"
        )
    

or "retrieve" instead of "list" for a route which includes PK.

This of course makes the entire path read-only so it's not a way to make some
fields writable and others not.

------
dopeboy
One metric that I'll measure a framework by is the likelihood of finding an
answer to a query that is _not_ articulated in the concepts and terms used by
the framework. This is especially useful when starting out.

DRF scores well here. It's designed in an intuitive way. The healthy community
around it is a big plus as well. Can't count the number of times I've come
across a SO article that had updated answers for the latest versions.

I only wish there was a way to make one time donations. Currently you have to
sign up for a recurring plan.

~~~
misterbowfinger
> One metric that I'll measure a framework by is the likelihood of finding an
> answer to a query that is not articulated in the concepts and terms used by
> the framework.

It's also important to measure the likelihood to have to find an answer in the
first place. There are vibrant communities around many frameworks, but it
doesn't make them all good.

Speaking as someone who went from DRF -> Rails -> back to DRF, I can say that
DRF is sufficiently confusing to understand and get started with. The problem
partially exists within Django itself, but DRF doesn't exactly help. It can
feel like pulling teeth to create a simple API with DRF. And, as the another
HN comment explains, DRF does a ton of "opt-in" work that can end up doing
more than you intended.

My biggest gripe with DRF is how coupled it is to the Django ORM. All of the
nice ViewSets are only useful if you have cookie-cutter Django models, but we
all end up changing them.

I tend to enjoy working with Ruby Grape APIs:

[https://github.com/ruby-grape/grape#basic-usage](https://github.com/ruby-
grape/grape#basic-usage)

No need to deal with 100 types of ViewSets, Serializers, Renderers, Parsers,
and so on. You just need to understand that data is being passed back and
forth. If you need something more complicated, just add it yourself.

I wish Python had something similar. Something that's between Django & Flask
in terms of complexity.

~~~
vmsp
Falcon maybe?

~~~
Rotareti
Some more options:

Eve:
[https://github.com/nicolaiarocci/eve](https://github.com/nicolaiarocci/eve)
Hug:
[https://github.com/timothycrosley/hug](https://github.com/timothycrosley/hug)
flask-restful: [https://github.com/flask-restful/flask-
restful](https://github.com/flask-restful/flask-restful)

~~~
Chris2048
Other than requiring MongoDB, I really liked Eves approach.

------
ralmidani
When I started flirting with Ruby and Rails for building a web app backed by a
JSON API, DRF is what convinced me to stick with Django. It has a ridiculous
amount of built-in functionality, but without making it hard to customize your
API. If you haven't used DRF, you really owe it to yourself to give it a try.

I can't wait to see support for real-time views. Is that in the cards for DRF
3.6?

~~~
sandGorgon
drf and ruby on rails are apples to oranges. you should probably compare
django and rails.

drf is usually compared to sinatra.

~~~
ralmidani
If you're looking at Django alone, Rails has more functionality for building
APIs. DRF is the package that makes Django on par with (in my opinion, better
than) Rails.

I see Sinatra as more similar to Flask than DRF.

------
ralmidani
I use Django + DRF along with Ember, and love the combination.

All the new schema generation functionality is interesting. It's probably just
a matter of time before someone builds a tool that reads the schema generated
by Django, and syncs the Ember models with it. That's currently one of the
drawbacks of using separate frameworks (and languages) for the client and
server.

~~~
postcarnival
I'm using that stack for two fairly large projects and loving it... I use the
ember-django-adapter to translate data on the client side (previously had used
drf json-api).. so far it's not too much hassle to build the ember models as
needed but I see what you're saying..

~~~
ralmidani
Why did you switch away from DRF JSON API? We used it for one project, then
realized how much of a hassle it was to get nested representations of data
(last time I checked, it didn't just work out of the box). But going back and
changing to Ember Django Adapter is a lot of work, since we have some custom
AJAX calls.

For a new project where we were starting from scratch, we stuck with Ember
Django Adapter.

------
elcct
I have a question about [http://www.django-rest-
framework.org/tutorial/2-requests-and...](http://www.django-rest-
framework.org/tutorial/2-requests-and-responses/)

Is it a good practice to handle all verbs in the function dealing with the
particular request as shown in the example?

I think for a real world scenario that would be a mess to read, but for a less
experienced developer this could hint that such approach is alright and result
in a less readable code base in the future.

~~~
scotu
If you proceed with the tutorial it is going to show you what I consider is
the cleanest way to go for views in django rest framework (ViewSets, coupled
with the routers, part 6 of the tutorial).

Basically, you will 1. split verbs to different methods of one class and 2.
you can not implement verbs you are not going to allow (you can of course do
that also with the functional style you see in the link you posted)

~~~
alexbecker
Having maintained a DRF-based API before, +1 to using ViewSets.

------
tschellenbach
I always miss DJRF when using languages other than Python

~~~
jpdlla
This. I've recently been working with a large project using Node. I find
myself constantly thinking about how I'd build it if I were using DRF.

~~~
aikah
> This. I've recently been working with a large project using Node. I find
> myself constantly thinking about how I'd build it if I were using DRF.

You wouldn't need to think about promises or callbacks at first place, which
would make things way easier. That's the main reason I gave up NodeJS for Go
when working with APIs. Async programming is noise. CSP is a better paradigm.

~~~
Cyph0n
Scala, Akka, and Play say hi!

~~~
findjashua
Don't you still need Futures for async stuff in order to not block the thread,
or is each request handled by a lightweight 'fiber' (erlang
process/goroutine)?

~~~
Cyph0n
That's correct, blocking operations within an actor need to be wrapped in a
Future[1]. But Akka itself can be extremely performant if the bulk of your
processing is non-blocking. Any non-blocking or long-running operations should
be executed in a separate thread pool (if there are many), or just a separate
thread.

[1]: [http://doc.akka.io/docs/akka/2.4/general/actor-
systems.html#...](http://doc.akka.io/docs/akka/2.4/general/actor-
systems.html#Blocking_Needs_Careful_Management)

------
tbarbugli
I can only say nice things about Django REST framework, super simple to use
and comes with lot of extras. Very interesting the shift towards schemas and
RAML; I am quite curious to see how usable that is.

------
Illniyar
For people who are unfamiliar, there is also Tastypie.

I find it's Model centric approach a whole lot nicer to work with then Django-
Rest .

~~~
dozzie
Which is basically stupid by itself, as you simply expose your internal data
structures without control or thought.

~~~
tbarbugli
care to explain?

~~~
dozzie
Data structures used internally for processing are something totally different
than data structures used for communication with outside world. Usually you
don't want to expose internals with public API, and even when you do, you want
to be very selective about what is shown and how.

When you publish internals, you only cement your implementation so you can't
change that easily later (e.g. when you realize how crappy it was at first),
and you even need to _pay for that drawback_ with ease of use of your API
(API's user would need to understand the system he talks with). It's a lose-
lose deal.

~~~
tbarbugli
I agree, I find doing this with DRF very easy and had the opposite with
TastyPie doing stuff I did not want or need. Having some ORM integration is
nice; there are a number of situations where it's easy to use your ORM safely
and get stuff done very quickly (eg. basic CRUD stuff for instance)

~~~
dozzie
"Basic CRUD" is basic only in most trivial situations, which by themselves are
rare. Much more often you need to create a set of related objects. With this
"basic CRUD" you have many points where network can break, and network
programming has one very important principle: network always breaks, so the
program has to survive in such case.

------
theptip
Anyone been using the new(ish) schema generation features? Sounds useful to be
able to generate client libraries from the API spec (e.g. DRF => swagger => JS
library), but I haven't felt compelled to do so. Any other use-cases that are
paying dividends?

~~~
rtpg
I was thinking about using it to auto-generate documentation, but I found
writing some ad-hoc tooling turned out to be more straightforward and
flexible.

~~~
theptip
Yeah, I've been using django-rest-swagger for docs, which has sufficed. Newer
versions of that package use the schema-gen stuff from DRF.

(A slight annoyance I've found here: the CoreAPI schema spec doesn't seem to
have a place to attach a top-level summary of the API, which is useful as a
'man page' for the rest of the API calls. Swagger does allow for that.)

------
resalisbury
there's a meetup in SF on DRF on wednesday (10/24/16), if you're interested in
learning more about DRF. [https://www.meetup.com/The-San-Francisco-Django-
Meetup-Group...](https://www.meetup.com/The-San-Francisco-Django-Meetup-
Group/events/234806317/)

------
jtchang
DRF is super nice to work with. It can be a bit slow when you start piling on
the serializers and such but dev time wise it gives you a significant boost in
productivity.

~~~
frankwiles
If you avoid nested serializers it isn't bad performance wise.

------
navyad
DRF with django its deadly combination.

------
lcnmrn
There’s no need for a framework since you can do:

values = User.objects.all().values('id', 'username')

results = json.dumps(values)

…or use the builtin JSON serializer. You can also use Paginator to paginate
the results.

~~~
mastazi
Your comment is being downvoted because DRF clearly does a whole lot more than
just serialising the response dictionary or adding pagination, you should
really have a look at the documentation.

However, I still think that Django should have something like the
"JSONResponse mixin example"[1] built-in by default; sometimes you are
building a product which is not an API but you still need the occasional
RESTful endpoint and, in those cases, something like DRF would be overkill.

[1] [https://docs.djangoproject.com/en/1.10/topics/class-based-
vi...](https://docs.djangoproject.com/en/1.10/topics/class-based-
views/mixins/#jsonresponsemixin-example)

~~~
ralmidani
You could always import DRF's serializers and parsers/generators without
committing to the entire framework.

Django does plan on bringing DRF's content negotiation into the main
framework:

[https://www.djangoproject.com/weblog/2015/dec/11/django-
awar...](https://www.djangoproject.com/weblog/2015/dec/11/django-awarded-moss-
grant/)

~~~
mastazi
Thanks, that would be a reasonably light-weight alternative.

------
snippet22
I just stopped from the js community to the Python one cause of js fatigue and
the first thing I learned is Django restful APIs and now this happens....

~~~
andybak
Now what happens? A well documented and almost entirely backwards compatible
release of one of Django's leading 3rd party additions?

