Skip to main content

A model form factory and admin class that includes reverse related fields

Project description

Django Reverse Relationship

Tests Code style: black

Rationale

Have you ever needed to manage a ManyToManyField on both sides of the relationship in the admin and found out that Django does not make this easy?

Example:

Consider the following models:

from django.contrib import admin
from django.db import models

class Topping(models.Model):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name


class Pizza(models.Model):
    name = models.CharField(max_length=255)
    toppings = models.ManyToManyField(Topping, related_name="pizzas")

    def __str__(self):
        return self.name


@admin.register(models.Pizza)
class PizzaAdmin(admin.ModelAdmin):
    fields = ["name", "toppings"]
    filter_horizontal = ["toppings"]


@admin.register(models.Topping)
class ToppingAdmin(ReverseRelationshipAdmin):
    fields = ["name", "pizzas"]
    filter_horizontal = ["pizzas"]

In this example, you can easily add the toppings field to PizzaAdmin, but trying to add pizzas to ToppingAdmin will raise the following error:

Unknown field(s) (pizzas) specified for Topping

This package solves this problem by providing the ReverseRelationshipAdmin:

from reverse_relationship.admin import ReverseRelationshipAdmin
from .models import Topping

@admin.register(Topping)
class ToppingAdmin(ReverseRelationshipAdmin):
    fields = ["name"]
    related_fields = ["pizzas"]
    related_filter_horizontal = ["pizzas"]

Customization

The following attributes can be used to customize the ReverseRelationshipAdmin class.

related_querysets

You can customize the queryset for related fields by passing a dictionary to related_querysets, where keys are the field names and values are the QuerySet instances. This allows you to limit the available options in the reverse relationships.

related_querysets = {
    "pizzas": Pizza.objects.filter(name__startswith="veggie"),
}

related_filter_horizontal / related_filter_vertical

Use these options to display reverse fields with Django’s FilteredSelectMultipleField widget, either horizontally or vertically.

related_filter_horizontal = ["pizzas"]

related_labels

You can specify custom labels for reverse relationships.

related_labels = {
    "pizzas": "Available Pizzas",
}

Hooks

Each of these attributes has a hook available (eg. get_related_querysets) than can be overwritten to customize the value based on the request object and/or model instance.

Use Outside of Admin

Use reverse_relationship_form_factory to create model forms with reverse relationships anywhere in your Django app.

from reverse_relationship.forms import reverse_relationship_form_factory 
from .models import Topping

ToppingForm = reverse_relationship_form_factory(
    model=Topping,
    related_fields=["pizzas"],
)

The generated HTML form will look like this:

<div>
    <label for="id_name">Name:</label>
    <input type="text" name="name" maxlength="255" required id="id_name">
</div>
<div>
    <label for="id_pizzas">Pizzas:</label>
    <select name="pizzas" id="id_pizzas" multiple>
        <!-- Whatever pizzas are in your database -->
        <option value="1">Veggie</option>
        <option value="2">Cheese</option>
        <option value="3">Mediterranean</option>
    </select>
</div>

Limitations

While primarily designed for ManyToManyField relationships, this package also supports ForeignKey relationships, but only if the foreign key is nullable.

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

django_reverse_relationship-0.1.0.tar.gz (29.6 kB view details)

Uploaded Source

Built Distribution

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

django_reverse_relationship-0.1.0-py3-none-any.whl (6.9 kB view details)

Uploaded Python 3

File details

Details for the file django_reverse_relationship-0.1.0.tar.gz.

File metadata

File hashes

Hashes for django_reverse_relationship-0.1.0.tar.gz
Algorithm Hash digest
SHA256 142365e76c336be7d7c63482219b1b00c4a448de011e331f4dce266fabf19f70
MD5 a563bdbf32f3b817c03f5cf6f1e4c38b
BLAKE2b-256 4630876781a385b94df84d66f596573b0b7a3078a4841e782f6c22a603c29e20

See more details on using hashes here.

File details

Details for the file django_reverse_relationship-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_reverse_relationship-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b8082808767f35fed04a792dd1eacb42f4307f908daa9d1528d504c69e38719c
MD5 b53ea262455bb79c9481a3bd88c65d80
BLAKE2b-256 7aadaf7e43f27035782a799b8276808b550ae011843905393a08e4236934c242

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