vivekv
vivekv

Reputation: 2298

Django OneToOneField and Admin UI

I am having a confusion on how to model a relationship in Django so that it can be edited inline in the Django Admin.

Let me explain the scenario.

I have a Customer Model and An Address Model. In the customer model I have a OneToOneField relationship to Address once for billing and once for shipping address.

class Address(models.Model):
    pass

class Employee(models.Model):
    billing_address = models.OneToOneField(Address)
    shipping_address = models.OneToOneField(Address)
    # Many more such fields

Now with this model there is no easy way to make them inline in Admin. I have tried the following

class AddressInline(admin.TabularInline):
    model = Address

class Customer(admin.ModelAdmin):
    inlines = [AddressInline, ]

I keep getting an error,

<class 'employee.admin.AddressInline'>: (admin.E202) 'employee.Address' has no ForeignKey to 'employee.Customer'.

Now I know there are other bugs similar to this one. ie. Use OneToOneField inlined in Django Admin and Django admin - OneToOneField inline throws "has no ForeignKey" exception

But I think my question is slightly different to warrant this post. Please help!

Upvotes: 3

Views: 596

Answers (1)

Sonic Park
Sonic Park

Reputation: 19

#1

models.py

class BillingAddress(models.Model):
    employee = models.OneToOneField(to=Employee, related_name='billing_address')

class Employee(models.Model):
    # Many more such fields

admin.py

class AddressInline(admin.TabularInline):
    model = BillingAddress
    extra = 1

@admin.register(Employee)
class EmployeeAdmin(admin.ModelAdmin):
    inlines = [AddressInline, ]

#2

models.py

class Address(models.Model):
    name = models.CharField(max_length=250)
    employee = models.ForeignKey(to=Employee, related_name='addresses')

class Employee(models.Model):
    # Many more such fields

admin.py

class AddressInline(admin.TabularInline):
    model = Address

@admin.register(Employee)
class EmployeeAdmin(admin.ModelAdmin):
    inlines = [AddressInline, ]

Full Example:

models.py

class Company(models.Model):
    pass


class CompanyScheduler(models.Model):
    company = models.OneToOneField(
        to=Company,
        related_name='scheduling',
        on_delete=models.CASCADE,
    )

    start = models.DateField()
    finish = models.DateField()

admin.py

class CompanySchedulerInLine(admin.TabularInline):
    model = CompanySchedulerInLine
    extra = 1


@admin.register(CompanyModelAdmin)
class CompanyModelAdmin(admin.ModelAdmin):

    inlines = [
        SchedulerInLine,
    ]

UI

enter image description here

Upvotes: 2

Related Questions