Skip to main content

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.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 UserSerializer in 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

inertia-django-0.1.1.tar.gz (6.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

inertia_django-0.1.1-py3-none-any.whl (7.0 kB view details)

Uploaded Python 3

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

Hashes for inertia-django-0.1.1.tar.gz
Algorithm Hash digest
SHA256 3c562db7b984fe45bc61ace92f4892f23bf3e83fd0608a7bbd4727d9e6c108b2
MD5 223dfa6c436c16273a0947a92dfc0dd1
BLAKE2b-256 3731576813b367b6d16dde9a03ab9a0e7594fdfc0a429bcbacacd3ad583d8048

See more details on using hashes here.

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

Hashes for inertia_django-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 acd3b65959c1f7eef89daaf066554883171675b3dcb8d8852d1df2c1d230c7e2
MD5 ebf173984e9cdeeef67c9c4b13302b90
BLAKE2b-256 0ae85917cede7a6cf9e87d448cb3b749ff31d6bdf600c6c575b64ca4fc76091a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page