[Django]-Django admin – OneToOneField inline throws "has no ForeignKey" exception

0👍

Another solution is moving the OneToOneField from Content to Page

class Content(models.Model):
    """Basic page data which can be used by other modules"""
    title = models.CharField(max_length=200)
    html_title = models.CharField(max_length=200)
    meta_desc = models.CharField(max_length=200)
    keywords = models.CharField(max_length=200)
    content = models.TextField()
    page = models.OneToOneField(Page, primary_key=True, related_name="content")

class Page(models.Model):
    """Concrete implementation of a basic page managed by the admin"""
    slug = models.SlugField()

    def __str__(self):
        return self.content.title

You can still do page.content and the inline form will work out of the box

EDIT:

One cons of that approach is that it will allow the user to create a page without assigning any content to it (in which case page.content will crash)

Its very easy to overcome this issue by creating custom form

class ContentAdminForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        kwargs["empty_permitted"] = False
        super(ContentAdminForm, self).__init__(*args, **kwargs)

Then in the admin page

class ContentInline(admin.TabularInline):

    model = Content
    form = ContentAdminForm
    fields = ('title', 'html_title', 'meta_desc', 'keywords', 'content')
👤Ramast

0👍

If you don’t want to change your models at all, there’s a django module to display the non-defining side inline: django_reverse_admin

You’ll need to add django_reverse_admin to your requirements.txt:

-e git+https://github.com/anziem/django_reverse_admin.git#egg=django_reverse_admin

Then import it:

admin.py

from django.contrib import admin
from django_reverse_admin import ReverseModelAdmin

from content.models import Page, Content

# don't need to define an inline anymore for Content

class PageAdmin(ReverseModelAdmin):
    fields = ('slug',)

    inline_reverse = ['content']
    inline_type = 'tabular'  # or could be 'stacked'
👤lynx

Leave a comment