Dale O'Brien
Dale O'Brien

Reputation: 4338

Reverse Inlines in Django Admin with more than one model

Say I have some django models, something like this:

class Address(models.Model):
    pass

class Person(models.Model):
    address = models.ForeignKey(Address)

class Store(models.Model):
    address = models.ForeignKey(Address)

class Company(models.Model):
    address = models.ForeignKey(Address)

So, in the Admin interface, I'd like to be able to edit a Person and have the Address in-lined.

I know it's possible to do this,

class Address(models.Model):
    person  = models.ForeignKey(Person, blank=True)
    store   = models.ForeignKey(Store, blank=True)
    company = models.ForeignKey(Company, blank=True)

class Person(models.Model):
    pass

class Store(models.Model):
    pass

class Company(models.Model):
    pass

Then I can do the usual,

class AddressInline(admin.TabularInline):
    model = Address

class PersonAdmin(admin.ModelAdmin):
    model = Person
    inlines = (AddressInLine,)

class CompanyAdmin(admin.ModelAdmin):
    and so on

But this then means that I'd have more than one address per person, and my Address model doesn't feel right any more.

Any help will be appreciated.

Upvotes: 8

Views: 3583

Answers (2)

Bulkan
Bulkan

Reputation: 2596

Try the following

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

class Address(models.Model):
    object_id    = models.PositiveIntegerField()
    content_type = models.ForeignKey(ContentType)
    of           = generic.GenericForeignKey('content_type', 'object_id' )

class Person(models.Model):
    pass

class Store(models.Model):
    pass

class Company(models.Model):
    pass

Then you can do this:

from django.contrib import admin
from django.contrib.contenttypes import generic

class AddressInline(generic.GenericStackedInline):
    model   = Address
    max_num = 1

class PersonAdmin(admin.ModelAdmin):
    model = Person
    inlines = (AddressInLine,)

class CompanyAdmin(admin.ModelAdmin):
    and so on

admin.site.register(Person, PersonAdmin)

Upvotes: 6

jpic
jpic

Reputation: 33410

Changing class AddressInline(admin.TabularInline) to class AddressInline(admin.StackedInline) will make the Address inline look less like it's possible to have several.

Set AddressInline.max_num to 1 if you want no more than 1 address per AddressInline.

Set AddressInline.extra to 1 if you want a blank address form when there is no related Address.

Documentation: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#inlinemodeladmin-options

Upvotes: 3

Related Questions