The Django adapter for Inertia.js.
Project description
Inertia.js Django Adapter
Warning: This project is in a very early stage and depends on another early stage library and its frontend adapters called Inertia.js.
Requirements
This package is meant to be used in a Django application and it uses django-rest-framework's serializers.
$ pipenv install django djangorestframework django-webpack-loader
Installation
There is still a few too many manual steps involved using inertia-django. I'm looking for ways (and people to help) to make the initial setup more smooth.
Install the inertia-django package from PyPI:
$ pipenv install inertia-django
Webpack 📦
INFO: For now it might be the easiest to take a look or clone the example repository.
You have to use webpack for the Dynamic Imports Feature. The following config is borrowed from the Django Inertia.js Example. It uses a few plugins that are not necessary like PurgeCSS, Tailwind, MiniCSSExtract, etc. But the important ones are:
- Webpack Bundle Tracker for Django Webpack Loader.
- Vue Loader is optional, but there is only the inertia-vue adapter yet.
webpack.config.js:
const path = require("path");
const BundleTracker = require('webpack-bundle-tracker');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const glob = require("glob-all");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const PurgecssPlugin = require("purgecss-webpack-plugin");
class TailwindExtractor {
static extract(content) {
return content.match(/[A-Za-z0-9-_:\/]+/g) || [];
}
}
module.exports = {
mode: 'development',
devtool: 'inline-source-map',
// TODO: adjust the entry points to your project
entry: ["./core/assets/js/index.js", "./core/assets/css/index.postcss"],
output: {
publicPath: "/static/bundles/",
filename: "[name]-[hash].js",
chunkFilename: '[name]-[hash].js',
path: path.resolve('./bundles/'),
},
plugins: [
new BundleTracker({ filename: './webpack-stats.json' }),
new VueLoaderPlugin(),
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: "[name]-[hash].css"
}),
new PurgecssPlugin({
paths: glob.sync([
// TODO: adjust the directories to your project
path.join(__dirname, "core/assets/js/**/*.vue"),
path.join(__dirname, "core/templates/index.html")
]),
extractors: [
{
extractor: TailwindExtractor,
extensions: ["html", "js", "vue"]
}
]
})
],
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env'
],
plugins: ["@babel/plugin-syntax-dynamic-import"]
}
}
},
{
test: /\.vue$/,
use: 'vue-loader'
},
{
test: /\.postcss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{ loader: 'css-loader', options: { importLoaders: 1 } },
'postcss-loader',
]
}
]
},
resolve: {
extensions: ['.js', '.vue'],
alias: {
'vue$': 'vue/dist/vue.runtime.js',
// TODO: adjust or remove, it's a convenient way to import js files in your components
'@': path.resolve('core/assets/js'),
}
},
}
Usage
render_inertia function
The easiest way to render a Vue component with inertia-django is to use the render_inertia function. Note: You have to have an Index.vue component in your project.
from inertia import render_inertia
def index(request):
# for function views just use the render_inertia function
return render_inertia(request, 'Index', props={'title': 'My inertia-django page'}, template_name='index.html')
This would be a bit much to write everytime so you can omit the template_name and set it in settings.py:
INERTIA_TEMPLATE = 'index.html'
After that you just have to call:
from inertia import render_inertia
def index(request):
# for function views just use the render_inertia function
return render_inertia(request, 'Index', props={'title': 'My inertia-django page'})
InertiaListView
inertia-django ships with a crude implementations of the generic ListView:
views.py:
class Index(InertiaListView):
# Inertia supports List and DetailViews right now
model = Contact
serializer_class = ContactSerializer
component_name = "Index"
Index.vue
<template>
<Layout>
<h2 class="mb-4">Contacts</h2>
<p>User: {{shared.user.username}}</p>
<ul>
<li :key="contact.id" v-for="contact in contact_list">
<inertia-link :href="'/contact/' + contact.id">
{{contact.name}}
</inertia-link>
</li>
</ul>
</Layout>
</template>
<script>
import { InertiaLink } from "inertia-vue";
import Layout from "@/Components/Layout";
export default {
props: ["contact_list", "shared"],
components: { Layout, InertiaLink }
};
</script>
InertiaDetailView
inertia-django ships with a crude implementations of the generic DetailView:
views.py:
class ContactView(InertiaDetailView):
model = Contact
serializer_class = ContactSerializer
component_name = "Contact"
props = {"test": True} # you can inject any props you want
Contact.vue:
<template>
<Layout>
<inertia-link href="/">Home</inertia-link>
<h2 class="mb-4">{{contact.name}}, {{contact.first_name}}</h2>
<p>Age: {{contact.age}}</p>
<p>Test: {{test}}</p>
</Layout>
</template>
<script>
import { InertiaLink } from "inertia-vue";
import Layout from "@/Components/Layout";
export default {
props: ['contact', 'test'],
components: { Layout, InertiaLink }
};
</script>
inertia.share function
If you want to have some basic props that are always injected, you can share them between Components:
I had to declare the
UserSerializerin apps.py so that it is available at startup. If somebody has a better idea feel free to create an issue.
e.g. apps.py:
from django.apps import AppConfig
from django.contrib.auth import get_user, get_user_model
from rest_framework import serializers
from inertia import share
def current_user(request):
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = get_user_model()
fields = ["username", "email"]
return UserSerializer(get_user(request)).data
class CoreConfig(AppConfig):
name = 'core'
def ready(self):
share('title', 'Django Inertia.js Example 🤘')
share('user', current_user)
As you might have recognized current_user is a function. While rendering inertia-django checks if a shared property is callable and if it is, it will call that function with the current request.
Example
Take a look at this repository for an example of how to use this package.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file inertia-django-0.1.1.tar.gz.
File metadata
- Download URL: inertia-django-0.1.1.tar.gz
- Upload date:
- Size: 6.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/41.0.0 requests-toolbelt/0.8.0 tqdm/4.31.1 CPython/3.7.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3c562db7b984fe45bc61ace92f4892f23bf3e83fd0608a7bbd4727d9e6c108b2
|
|
| MD5 |
223dfa6c436c16273a0947a92dfc0dd1
|
|
| BLAKE2b-256 |
3731576813b367b6d16dde9a03ab9a0e7594fdfc0a429bcbacacd3ad583d8048
|
File details
Details for the file inertia_django-0.1.1-py3-none-any.whl.
File metadata
- Download URL: inertia_django-0.1.1-py3-none-any.whl
- Upload date:
- Size: 7.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/41.0.0 requests-toolbelt/0.8.0 tqdm/4.31.1 CPython/3.7.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
acd3b65959c1f7eef89daaf066554883171675b3dcb8d8852d1df2c1d230c7e2
|
|
| MD5 |
ebf173984e9cdeeef67c9c4b13302b90
|
|
| BLAKE2b-256 |
0ae85917cede7a6cf9e87d448cb3b749ff31d6bdf600c6c575b64ca4fc76091a
|