Setup django social auth with vuejs frontend - django

I just started a project with a frontend developer. We are trying to add social authentication (Discord), without success.
I want to use django as a REST API for the backend, I installed django-allauth which seems to work when I use a django template to connect using Discord:
{% load socialaccount %}
{% providers_media_js %}
<html>
<head>
<title>Discord Registration</title>
</head>
<body>
{{user}}
Discord Connect
</html>
But I have no idea how to share this connection with the frontend (made with vuejs). I've never worked on a project where backend and frontend are not in the same application... What to do on the frontend and what to do on the backend? And the main question, how? I've been working on it for two days and I'm still completely lost.

There are 2 ways you can make this work depending upon how you are planning to deploy to production.
Method 1:
Frontend developer can run npm run build command which will generate a folder called dist. You have to serve this folder from your django application. Do the following in your Django application:
In settings.py file, add VUE_FOLDER = 'PATH_TO_DIST_FOLDER/dist'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, VUE_FOLDER)],
}
In urls.py file, add path('', TemplateView.as_view(template_name='index.html'), name="home"
The above line will serve the Vue index.html file as django home page.
This way your production will have only one port which will serve only one application which has both UI and django app. All API which are present in urls.py file can be accessed by UI. No need to worry about CORS.
Method 2:
UI can be a separate app hosted in one port and your django application can be a separate app hosted in another port. In that case your django application should support CORS as all API calls from UI will be considered as cross origin calls. UI should include the complete url path http://django-server:port/api_name/ to access the API.
In both the case, you no need to use django template and UI can be an independent app. Routing will be taken care by vue-router. Django app will act as server and will handle only APIs. Hope this helps.

Related

What is the original purpose of Django apps? What are the use cases of Django apps?

I'm building a website that'll use a Bootstrap template similar to the image shown below. I intend to add an authentication and authorization functionality using OAuth 2. The main menu will consist of:
Homepage link
Statistics app link
NLP app link
Computer vision app link
Contacts page link
Login button
Without using Django, the homepage would just be index.html, the Statistics app would be a statistics.html page which interacts with the backend to show some plots, the NLP app would be an nlp.html page which interacts with the backend to display some NLP processed text and so on.
When using Django, how am I supposed to structure it? Should I create a separate NLP Django app, and a separate Statistics Django app and a separate Homepage Django app? I'm already surprised that I had to create an app just to be able to have a homepage, and then had to add path('', include('homepage.urls')), to urlpatterns to redirect / to the homepage app.
If I use the Bootstrap template for the homepage app, then how would I share the JS files, the CSS files and other boilerplate files of the template with the other apps of my website? Once the user logs in, would the session of the homepage app be valid for the other apps too?
Do I even need to create separate apps for NLP, Statistics, computer vision etc? What exactly is the purpose of Django apps, and could you mention a few use cases of Django apps and how boilerplate template files and scripts were shared among apps? Any best-practices related to app building?

Is there a way to integrate Django with Next.js?

I've integrated Reactjs with Django by having a function to access build/index.html. The below codes show how I do that.
config/urls.py
urlpatterns = [
...
re_path(r'search/', react_views.ReactAppView.as_view()),
]
PROJECT_NAME/views.py
class ReactAppView(View):
def get(self, request):
try:
with open(os.path.join(str(settings.BASE_DIR), 'frontend', 'build', 'index.html')) as file:
return HttpResponse(file.read())
except:
return HttpResponse(
"""
Build your React app.
""",
status=501,
)
ReactAppView function accesses index.html which is created with yarn build on React side. Basically, I used React just for search view, and other than search view, I used jQuery as it was developed with jQuery first.
Since I found that I need Next.js to use Server Side Rendering (SSR) with React, I've been trying to migrate React app to Next.js. But, Next.js doesn't have index.html. It just has pages/index.js instead.
I've tried very hard to figure out how to integrate Django with Next.js, but I can't find any helpful resource. Can anyone help me about this?
It seems like you want to serve static files (i.e. React or Next.js bundles).
Django has a guide on how to do this (via django.contrib.staticfiles)
The simplest example (straight from the docs) is:
set the STATIC_FILES folder:
STATIC_URL = '/static/'
Put the index.html file there and reference it as /static/index.html.
For more info on staticfiles, please refer to the official documentation: https://docs.djangoproject.com/en/4.0/howto/static-files/
On the Next.js side, you need to either follow the sample at https://nextjs.org/docs/advanced-features/static-html-export or create manually an index.html that includes all next.js bundles that you are using.
I know it's too late, but Ored's answer is not working with Nextjs.
When using a React SPA, all of the react code will run on the client's browser, and of course in that case all you need is just serve the React build artifacts as staticfiles.
But with Nextjs using SSR, you need to run the Nextjs server (using Nodejs) and you should integrate these 2 servers (Django and Nextjs) to work together.
So, if you are starting a new project you should just use Django as a web service and let Nextjs to be the interface of your application, but if you already have a Django application and want to use Nextjs, check out following article and GitHub repo:
Medium: Django + Next.js The Easy Way
Github: django-nextjs

Communication between Django and React

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

Django: How can I serve an angular app without using STATIC_URL during development?

I have a django project which is making use of django-rest-framework to provide an api for an angular client.
The entire angular app is developed separately to the django project, and doesn't make use of any django templates or suchlike.
Eventually the angular app will be served as a static asset via nginx or something along those lines.
However, during development, I would like the django development server to serve the angular app.
The issue I have is that none of the static assets in index.html are prefixed with STATIC_URL or a similar static prefix which django can look for.
Attempting to serve all non-api routes as static files as such:
urlpatterns += static(r'', document_root=settings.ANGULAR_APP_ROOT)
gives an exception
Empty static prefix not permitted
I know that in nodejs express server you can use something like:
app.use(express.static(path.join(config.root, 'app')));
which works seamlessly. I guess it searches for any paths in the configured folder and if any match the requested url, serves them.
I do not want to force django specific code/prefixes into the angular app (ala STATIC_URL etc)
What I'm looking for is some middleware which will offer a fallback route for anything unmatched by the existing urlpatterns and search a filesystem path for a matching asset and serve it if found.
Is it possible to get the static assets served like this with the django development server?

Shopify Django app failing in shopify_app/views.py in finalize

I created a Shopify app hosted on Heroku. I had to modify the name of the shopify app from shopify_app to shopifyapp for Heroku to recognize it as a Django app.
If I visit my app directly though app-name.herokuapp/login and connect the app to my store, It correctly pulls my recent orders and products.
If I visit the app through the app menu and it redirects to app-name.herokuapp/login/finalize it shows
KeyError at /login/finalize/
I haven't modified anything in shopify_app except changed it's name to shopifyapp everywhere.
I suspect since the app cant finalize, that is why the links like this also don't work:
https://{{ current_shop.domain }}/admin/orders/{{ order.id }}">{{ order.name }}
They just direct to something like
https://admin/orders/000000000
Can anyone help troubleshoot this problem with the shopify app?
I've made my app repo public since it's still essentially just the demo app:
https://github.com/dpetrillo740/scm
App is running at http://scmapp.herokuapp.com/
This was a bug in the demo App. I just fixed it with this commit 27d5091.
Update the path in your application url to /login from /login/finalize. The redirect_uri is now provided for authentication with shopify, so it will still redirect back to the finalize endpoint.