user2872147
user2872147

Reputation: 219

One to One field Django Admin

Edited to use a one-to-one field

I'd like to add the area of a building to a django modeladmin. The table structure is

class Area(models.Model):
    id= models.IntegerField('Buildings', db_column='id')
    area=models.FloatField(blank=True, null=True)

class Buildings(models.Model):
    id = models.AutoField(primary_key=True)
    auto_sf = models.OneToOneField(Area, db_column='id')

I know that I can access the area attribute by using

b=buildings.get(id=1)
print(b.area.area)

But I don't understand how to incorporate b.area.area into the modeladmin - since this doesn't work.

class AdminSection(admin.ModelAdmin):
        
    def area(self, obj):
           return obj.area.area

    fields=(('id','area'))

Upvotes: 6

Views: 15822

Answers (2)

As shown below, if "Building" class has "models.OneToOneField()" referring to "Area" class which means "Building" class has the ForeignKey referring to "Area" class:

# "models.py"

from django.db import models

class Area(models.Model):
    name = models.CharField(max_length=100)

class Building(models.Model):
    name = models.CharField(max_length=100)
    area = models.OneToOneField( # Here
        Area, 
        on_delete=models.CASCADE,
        primary_key=True
    )

Then, you can inline "Building" class under "Area" class as shown below:

# "admin.py"

from django.contrib import admin
from .models import Area, Building

class BuildingInline(admin.TabularInline):
    model = Building

@admin.register(Area)
class AreaAdmin(admin.ModelAdmin):
    inlines = (BuildingInline, )

As shown below, if "Area" class has "models.OneToOneField()" referring to "Building" class which means "Area" class has the ForeignKey referring to "Building" class:

# "models.py"

from django.db import models

class Building(models.Model):
    name = models.CharField(max_length=100)
    
class Area(models.Model):
    name = models.CharField(max_length=100)
    area = models.OneToOneField( # Here
        Building, 
        on_delete=models.CASCADE,
        primary_key=True
    )

Then, you can inline "Area" class under "Building" class as shown below:

# "admin.py"

from django.contrib import admin
from .models import Area, Building

class AreaInline(admin.TabularInline):
    model = Area

@admin.register(Building)
class BuildingAdmin(admin.ModelAdmin):
    inlines = (AreaInline, )

Upvotes: -2

user764357
user764357

Reputation:

As stated, you are looking to use an inline model admin, like so:

class AreaInline(admin.StackedInline):
    model = Area
class BuildingAdmin(admin.ModelAdmin):
    inlines = (AreaInline, )
admin.site.register(Building, BuildingAdmin)

Also, your models should ideally have singular names, i.e. Building, to make the more semantic sense - e.g. A building has an area. Unless the Buildings object is literally managing multiple buildings per instance.

Upvotes: 5

Related Questions