I'm trying to setup a project using Django for backend and React for frontend. The project has several screens, a lot of information in DB and images generated by the backend, and will include some authentication and user permissions for different screens.
According to what I found - the best way to do it is having Django render an html file:
def index(request):
return render(request, 'frontend/index.html')
which references a .js file:
<script src="{% static "frontend/main.js" %}"></script>
Which is created using Webpack.
This main.js retrieves the data it needs from Django using a REST api:
fetch("...some Django endpoint..").then(response => ... this.setState(...retrieved data...))
Unlike when just using Django for backend + Django templates for frontend where the backend can just send the context directly to the template:
def index(request):
context = {'information': .... retrieve info from DB}
return HttpResponse(loader.get_template('bla/index.html').render(context, request))
and the template can use this info directly, without referencing the backend again:
{% for bla in information %}
I'm wondering if it is a reasonable setup?
It seems excessive to have the frontend use REST for retrieving each piece of information it needs and the backend exposing another REST api for each part of data it needs to supply (Instead of just pushing all of the information to a single dict and sending it over along with the template),
Also, it requires at least 2 RTTs to render the full page (which I guess usually is okay)
According to what I found - the best way to do it is having Django render an html file:
I disagree with this line. I would say it would be best to keep the react app and Django app totally separate.
I believe, the Django application should solely provide APIs and adminsite(maybe, depending on your needs).
And the frontend should be a standalone app which can be served through NGINX/ExpressJs/Apache etc.
There are several advantages of this setup.
From Django application's perspective, the advantages are:
Django will not be burdened to serve the Frontend. Use gunicorn or uwsgi to serve the Django APIs.
As Django will provide data through API only, it will provide clarity on how the frontend application will communicate with the backend. I know that you can send data using context when Django serves the react app, but this might cause confusion because of API and context's co-existence.
You can use Token based authentication, JWT etc instead of Django's own session based authentication, which have a lot of other advantages.
Freeing your frontend application from backend is the best thing can happen for the frontend. Like for example:
if you had Django to serve the frontend, you were almost forced to use session based auth(its not like you can't use other auths, but whats the point of having multiple auth systems)
You couldn't have used server side rendering with Django rendering the frontend.
Lets say, you are have no idea about how Django works, but you will be forced to setup a Django application in your local machine, because it serves the frontend.
You couldn't have used ExpressJs to serve the frontend, or use the advantages of using NGINX to serve those contents.
Deployment would be complicated if you have docker setup. In this case, you would have had to use one Docker Container to serve everything, else you could have used multiple docker containers to serve backend/frontend.
Lets say, you want to serve the Django application in one server, frontend from other server, but with Django tightly coupled with Frontend, you can't do this setup.
You can easily connect external RESTful API services without bothering about Django. Even you can use any other frameworks like Tornado, Flask etc(but DRF+Django ORM is awesome) to develop APIs.
There are some more generic advantages of having backend and frontend separated.
There is a fantastic tutorial which you can read on medium about setting up separate Django + ReactJs app.
You can use GraphQL, it has several advantages over REST, f.e.:
only one endpoint for entire app;
ability to fetch data with relations between them;
easy data structure modifications on both sides;
advanced client with cache/normalization/subscriptions/optimistic updates (I prefer apollo to relay);
can be used as datasource for static site generation (SEO);
you can stich other services/APIs;
... many more.
Using react Server Side Rendering you can get pages without additional requests - 'prefilled'/rehydrated, ready for interactions - better Time to Interactive.
Tutorial/demo: django-graphql-apollo-react-demo
Related
I'm used to Django and already developed website with a whole Django or with Django API + React.
For a side project, I'm thinking about creating a Django project with 2 apps:
Django API 2) Django Front.
I absolutely want to decouple front/back to be able to reuse the API in the future, and I like the view system from Django.
Is my idea making sense?
Edit 1:
To clarify.
App 1: Django API serving JSON.
App 2: Django App using API calls in the controllers to generate the views.
Edit 2:
I did a proof of concept and it works like a charm.
The only drawback is that I have to use Cookies to store the JWT token and maintain the session state, which is not convenient
it is possible, but completely wrong with idea.
How it possible. Wrong version:
Try to remember, how we can create integrate test for our view. We Should create client and send request to Django to your view-url with args kwargs querystring e.t.c.
In response you have already answer. Try to imagine: part with client - is your Django front, requested part - your backend.
The same works not only in test, you can create request to ask something on the completely other server.
Redis/MemCashed e.t.c. (pattern sender/receiver) Wrong version:
The Front Django speaks with Backend through Third part application. It can be faster.
"Pythonic" version. Right in your case:
You can create Backend Django part like a library with views as interfaces.
Frontend Django part is completely standalone, it import an use interfaces from library, which is your "BackEnd Module".
If you want - you can use "BackEnd Module" everywhere as import, or you can start it as server and ask info per requests.
Completely independent in this case means, you can install "BackEnd Module" without "FrontEnd Module". "FrontEnd Module" can be installed standalone too and it should take from settings, which interfaces should be used as data-source.
I hope, i am right understand your question.
You could definitely separate front and back, remember, django just creates endpoints and consumes them with its own views, you can even use both.
Here is the documentation for django views: https://docs.djangoproject.com/en/4.0/#the-view-layer
You can use a librarie like React as frontend and connect to your api(django app) and use both.
I want to build a project with Django framework, it includes website and mobile app, website is built based on Django template, and mobile app needs rest api. How can I do it with only one copy of source code?
In other words, can I create one project, in which there are several django apps, it supports returning both rendering template and json for mobile app?
I know we can use Angular JS in website, then both website and mobile app access rest api build with Django-Rest-Framework. But I have no idea about Angular JS and there is no time for me to learn it.
Please help.
This is easy to achieve if you leverage the power of HTTP headers, specifically speaking the "Content-Type" header
(HTTP 1.1 headers specification)
The way I personally use it is something like this:
def my_view_name(request):
if 'CONTENT_TYPE' in request.META and \
request.META['CONTENT_TYPE'] == 'application/json':
return HttpResponse(
json.dumps({"foo":"bar"}),
content_type='application/json'
)
else:
return render_to_response(
'sometemplate.html', context
)
The code above is django-specific.
It allows you to control what kind of response the server doles out, based out what the client passes in. It can detect that a JSON response is needed by checking the Content-Type header.
Just ensure your mobile app makes its HTTP requests with the Content-Typeheader set to application/json
Hope that's what you wanted.
You can do it in one project. Have the same Model, but have different views for website and REST-api.
You can build one Common Backend to serve your data.
And you can do this without having a Django-rest-Framework(without having to use angular).
You are just going call the url of the backend.
For eg.,. lets say backend code is running at 127.0.0.1/8000, and you need to get a user's details, you are just going to call url 127.0.0.1:8000/get_user_details/ from mobile app or any other front end.
And please make a habit of forming/arranging data written in a different function so that it is reusable by both the Mobile app and the website.(plz see below)
### For browser website written in DJANGO (served in template by django):
def user_details_page(request):
get_user_details(someid) #### returns json of user details
render in template
#### And for the mobile App you could use **get_user_details(someid)** just to get json data.
def get_user_details(someid):
###do watever
return json ## of user details
And you can also use Django Rest Framework(without having to use angular), it gives you a lot of stability.
Or you can setup a entire new backend in Django Framework to serve data for mobile App.
I am not able to comprehend what would be pros and cons of the following approaches in making a single page backbone application using RESTful APIs from Django Rest Framework.
Render the whole app from within Django's template.
Serve the backbone app from another server ie node server. With nginx in the front for both servers.
Serve the HTML/Templates and JS from a separate CDN.
What are the things to take care ie points of caution in each strategy. Is there any other way to tie them up which I am missing?
This is a very broad question, and really it has nothing to do with Django or Backbone. What you're really asking about is a "thick-client" architecture vs. a "thin-client" architecture. In other words, having your user interface rendered on the client vs. having it rendered on the server.
First, allow me to recap a few things to make sure we're on the same page. The "thin-client" approach is the traditional/old school model, and the model Django itself is based on. The server renders HTML, sends it to the client, and whenever the client wants to do something it sends data back to the server and asks for fresh HTML.
In contrast the more modern "thick-client" approach lets the client render all of the UI. Whenever the client needs to do something it makes an AJAX request to a (presumably REST-ful) API, powered by a library like Django REST Framework. That API just returns the relevant data, and leaves it up to the client to render it appropriately.
There are advantages and disadvantages to both approaches, but the thick-client approach is becoming more and more popular because:
network transactions are faster: because your server is only sending the exact JSON you need instead of a mess of HTML, the "payload" of the response is much smaller
you can fetch all data "behind the scenes"; this makes things appear faster to the user, and lets you implement UI paradigms (eg. infinite scroll) that a thin client can't
the client/server relationship is simpler, because the people writing server code never have to even think about HTML or any other presentation logic; they get to just focus on the data (which, being server engineers, is probably the part they're most interested in anyway)
This is why a lot of companies (including the one I work for) have all but abandoned Django proper in favor of API endpoints served by Django REST Framework.
So, if you want to go with a thick client architecture, Django should never serve anything except the very first HTML page (and even that could be served by ngnix if you wanted, since it's just static HTML). After that you'd use a Backbone.Router and Backbone.Views to render your site. Whenever you need new information from the server you'd fetch a Backbone.Model or Backbone.Collection (with its url property pointing to your Django REST Framework endpoint).
I can attest that this whole approach works great; the site I work on is very complex, with many endpoints, and Backbone + Django REST Framework handles it beautifully. The only (slightly) tricky part is caching: in the thin client approach the browser automatically caches pages for you, but since there are no "pages" in a thick client (just AJAX responses with data) there is no automatic caching. This means that if you want to cache data you'll need to do it yourself, for instance with a Backbone.Collection devoted to that purpose.
Hope that helps.
P.S. Back in the day Django REST Framework didn't handle Django authentication stuff (ie. logging in/out) quite the way we wanted, so we wound up serving one other page, our login page, from Django. However I'm pretty sure the current Django REST Framework handles authentication stuff much better now, so this likely won't be an issue for you.
I am very new to the world of web development and MVC architectures. I am currently working on django which i believe is an MVC framework. if i am right, for a web application MVC implies
views is the front end
models is the backend
controllers are the glue between frontend and backend
well if the above is true and views are the only frontend parts what exactly is the function of frontend frameworks like backbone, angular? how exactly do they deploy the mvc concept? Also when building a simple blogging site which framework would be preferrable? and also are there instances of websites working on both frontend and backend mvc frameworks? please give examples. for clarification i went through this question: In the Model-View-Controller principle, what is the Frontend and what is the Backend? but couldnt understand fully. thank you
There is no one-on-one analogy of front- and backend and the MVC model. For example, the admin of a (Django) site is generally considered to be part of the backend - it is not the part of the site the user will see - but part of the admin is definitely the View part of the MVC model. Anything a normal web user sees and/or directly interacts with is part of the frontend, everything else is part of the backend.
Now what is the MVC framework used in Django? We have:
The Model: this is the part of the application that holds the state of the application. In Django, a big part of this is the database and it's abstraction layer, the Django models. Other parts are user sessions and the request variable.
The View: this is the part of the application that presents the state of the application to the user. Django views and templates are responsible for this. Any data you see when you open up the website is the View part of MVC. The overall presentation is also part of this.
The Controller: this is the part of the application that represents any action you, the user, takes. Django is not truly a separated MVC framework because the View part and the Controller part are so tightly interwoven: any link, form or button you see on the site is a controller. It tells the site to do an action, such as present a different view (e.g. a link), or change the state of the model (e.g. an edit form).
What about Backbone or Angular? Why do you need two different MVC frameworks in a single application?
Django is a server-side framework. Every action happens on the server. If you click a link or submit a form, you send a request to the server and the server sends back a complete, static response (static in the sense that the page doesn't change once it's in your browser). You can't use Django to use logic client-side, as it is a python framework that runs on your server, not in your client's browser. Instead, it's Javascript's job to add any client-side logic, e.g. to reorder a list of items on the page or to dynamically add a new one. Now each page can be seen as some kind of mini-application.
Backbone and Angular are examples of MVC frameworks for such client-side applications. It supplies the client-side application logic that a server-side framework such as Django lacks, and surprisingly the people who like an MVC framework to develop a server-side application generally also like to use an MVC framework to develop a client-side application.
Django is a kind-of hybrid version of the Model-View-Controller model. The Django documentation generally describes it as a Model-View-Template model instead. Generally, the template (Django HTML with template tags, etc.) is generally matched to the normal View, providing the user's view in the way of web pages. The view in Django generally takes the place of the Controller, as it works between the Model, taking data from databases and defining new objects, and the View, which in this case is the Template. The Model is the same as normal in Django, providing the definition for different objects. So while the Model-View-Controller is normally the model for most languages, it is more so a Model-View-Template model, with the View being different than it is normally. Read more below:
http://jeffcroft.com/blog/2007/jan/11/django-and-mtv/
I am looking at Django, and patterns for web development.
What I am favoring at the moment(2014-01) is.
Use Django (restful/json) as the MC, Model/controller, or backed data and logic.
The controller part in Django refers to business rules and access control.
then use a javascript framework and bit of html as the client side code. View/controller.
In practice, the client/browser loads a javascript program, View/controller that then does restful queries to the backed model/controller
I'm trying to wrap my head around combining a client-side framework like AngularJS with Django. One thing that's really confusing me is the issue of routes and REST.
I've been trying to read a lot about it online, but documentation is limited, especially in terms of Django being combined with Angular (little snippets here or there). I understand that I need to add a REST framework like TastyPie to make a robust REST interface in my app in order for Angular to plug in and grab resources.
However, I'm confused as to how to properly map out my routes in such a way that (1) my server-side app can render my single-page app (SPA) with angular plugged in (2) routes that are supposed to load information/render templates (angular) and retrieve data from the server (django) don't conflict. Like if I have someone going on my website and doing site.com/user/1234 - that route is associated with both the Angular route and the Django route - except one renders a template and the other spits out JSON based on what is retrieved from the DB/server.
In addition, by using the REST api, do I forego a lot of the advantages I have in terms of having ModelForms being synchronized with my Models, etc? Is there any way to maintain this with AngularJS or do I have to look towards an AngularJS substitute.
The question isn't really specific to Django - just a matter of understanding the relationship between back-end and front-end in an SPA.
Routes are not duplicated between the back-end and the front-end. Your Django routes should be set up like:
/api/foo
/api/bar
...
and one single route that delivers a single page full of HTML partials, e.g.
/
The rest of the routes will be defined in Angular, e.g.
/articles/234
/blog/date/slug
...
The Angular controllers that handle those public-facing routes will in turn make $http calls against the API URLs and each will deliver one Angular partial. So there is no duplication, no overlap.
To the second part of your question, you can still use the Django ORM model relationships when constructing your API data, but yes, you'll lose all of that Django goodness when building the front-end.
If you build your API right, all of the data you need in each view will be fully present in the JSON feed that Angular consumes in that view. So you're using the ORM for back-end data construction, but you can't just decide to traverse a model relationship in a template without first preparing the back-end data to provide data for it.
Yes, it's a very different way of thinking of things, and yes it's quite a bit more complex than doing straight Django (or Rails). That's the cost of building a web app rather than a web site.