Home > Net >  Django many to many field not showing on admin - Legacy database
Django many to many field not showing on admin - Legacy database

Time:11-27

I want to show a many to many field that was created in nocodb on django admin panel. Therefore the database schema were created by nocodb. I want to also edit the db with django.

The many to many tags field doesn't show in django admin. There is no error message. Can someone help?

I used inspectdb to create the models and admin_generator to create the admin code for the nocodb fields.

I tried adding an id column in the join table. I made it the primary key. That didn't seem to help.

=================================================

The following pic shows that the tags are not shown on the page.

I want the following field on the page.

tags = models.ManyToManyField(Nc2BfwTag, through="Nc2BfwNcM2MNc2BfwNoteNc2BfwTag", blank=True)

field not showing up

=================================================

This is how it looks in nocodb.

This is how it looks in nocodb

=================================================

These are the tables in mysql. You can see the note table, tag table, and the note-tag table.

tables

=================================================

This is a post tagg many to many I created in Django, and it works.

taggs = models.ManyToManyField(Tagg)

enter image description here

=================================================

The models.py and admin.py follow:

models.py
# =================================================

class Tagg(models.Model):
    title = models.CharField(max_length=45, blank=True, null=True)

    def __str__(self):
        return  str(self.id)   " - "   self.title

class Post(models.Model):

    # Fields
    created = models.DateTimeField(auto_now_add=True, editable=False)
    last_updated = models.DateTimeField(auto_now=True, editable=False)
    title = models.CharField(max_length=230)
    body = models.TextField(max_length=32100, default=None, blank=True, null=True)
    taggs = models.ManyToManyField(Tagg)

    class Meta:
        pass

    def __str__(self):
        return str(self.pk)

# =================================================

class Nc2BfwTag(models.Model):
    title = models.CharField(max_length=45, blank=True, null=True)
    created_at = models.DateTimeField(blank=True, null=True)
    updated_at = models.DateTimeField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'nc_2bfw__tag'
    def __str__(self):
        return  str(self.id)   " - "   self.title

class Nc2BfwNcM2MNc2BfwNoteNc2BfwTag(models.Model):
    nc_2bfw_tag_c = models.OneToOneField('Nc2BfwTag', models.DO_NOTHING, db_column='nc_2bfw__tag_c_id', primary_key=True)  # Field renamed because it contained more than one '_' in a row.
    nc_2bfw_note_p = models.ForeignKey('Nc2BfwNote', models.DO_NOTHING, db_column='nc_2bfw__note_p_id')  # Field renamed because it contained more than one '_' in a row.

    class Meta:
        managed = False
        db_table = 'nc_2bfw___nc_m2m_nc_2bfw__note_nc_2bfw__tag'
        unique_together = (('nc_2bfw_tag_c', 'nc_2bfw_note_p'),)

class Nc2BfwNote(models.Model):
    title = models.CharField(max_length=45, blank=True, null=True)
    tags = models.ManyToManyField(Nc2BfwTag, through="Nc2BfwNcM2MNc2BfwNoteNc2BfwTag", blank=True)
    created_at = models.DateTimeField(auto_now_add=True, editable=False)
    updated_at = models.DateTimeField(auto_now=True, editable=False)
    body = models.CharField(max_length=45, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'nc_2bfw__note'

# =================================================

====

# admin.py
# =================================================
from django.contrib import admin
from django import forms
from . import models
from django.utils.html import format_html
# old.. from django.core.urlresolvers import reverse
from django.urls import reverse
from django.http import HttpResponseRedirect
from django.template.response import TemplateResponse
# =================================================
from .models import Tagg,  Post, Nc2BfwTag, Nc2BfwNcM2MNc2BfwNoteNc2BfwTag, Nc2BfwNote

@admin.register(Tagg)
class TaggAdmin(admin.ModelAdmin):
    list_display = ('id', 'title')

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    list_display = ('id', 'created', 'last_updated', 'title', 'body')

# =================================================

# @admin.register(models.Nc2BfwTag)
class Nc2BfwTagAdmin(admin.ModelAdmin):
    list_display = ('id', 'title', 'created_at', 'updated_at')
admin.site.register(models.Nc2BfwTag, Nc2BfwTagAdmin)

# @admin.register(Nc2BfwNcM2MNc2BfwNoteNc2BfwTag)
# class Nc2BfwNcM2MNc2BfwNoteNc2BfwTagAdmin(admin.ModelAdmin):
#     list_display = ('nc_2bfw_tag_c', 'nc_2bfw_note_p')
#     list_filter = ('nc_2bfw_tag_c', 'nc_2bfw_note_p')

@admin.register(Nc2BfwNote)
class Nc2BfwNoteAdmin(admin.ModelAdmin):
    list_display = ('id', 'title', 'created_at', 'updated_at', 'body')
# =================================================

CodePudding user response:

Django admin can't display the ManyToManyField if you specify an intermediate model, because the intermediate model may require more information (it may have more fields than the required ones). You can view the docs about here: https://docs.djangoproject.com/en/3.2/ref/contrib/admin/#working-with-many-to-many-intermediary-models

However, you can use the inline admin models to edit the values for that field.


class Nc2BfwNcM2MNc2BfwNoteNc2BfwTagAdminInline(admin.TabularInline):
    model = Nc2BfwNcM2MNc2BfwNoteNc2BfwTag
    extra = 1


@admin.register(Nc2BfwNote)
class Nc2BfwNoteAdmin(admin.ModelAdmin):
    list_display = ('id', 'title', 'created_at', 'updated_at', 'body')
    inlines = (Nc2BfwNcM2MNc2BfwNoteNc2BfwTagAdminInline,)

  • Related