【问题标题】:Django many to many field not showing on admin - Legacy databaseDjango 多对多字段未显示在管理员上 - 旧版数据库
【发布时间】:2021-11-25 22:48:59
【问题描述】:

我想在 django 管理面板上显示在 nocodb 中创建的多对多字段。因此数据库模式是由 nocodb 创建的。我还想用 django 编辑数据库。

django admin 中不显示多对多标签字段。没有错误信息。有人可以帮忙吗?

我使用 inspectdb 创建模型,使用 admin_generator 创建 nocodb 字段的管理代码。

我尝试在连接表中添加一个 id 列。我把它作为主键。这似乎没有帮助。

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

下图显示标签没有显示在页面上。

我想要页面上的以下字段。

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

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

这就是它在 nocodb 中的样子。

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

这些是mysql中的表。可以看到note表、tag表、note-tag表。

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

这是我在 Django 中创建的多对多的帖子标签,它有效。

taggs = models.ManyToManyField(Tagg)

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

models.py 和 admin.py 如下:

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')
# =================================================

【问题讨论】:

    标签: django many-to-many


    【解决方案1】:

    如果您指定中间模型,Django 管理员将无法显示 ManyToManyField,因为中间模型可能需要更多信息(它可能具有比所需字段更多的字段)。你可以在这里查看文档:https://docs.djangoproject.com/en/3.2/ref/contrib/admin/#working-with-many-to-many-intermediary-models

    但是,您可以使用内联管理模型来编辑该字段的值。

    
    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,)
    
    

    【讨论】:

    • 谢谢。它确实在那里说得很清楚。我希望我能在这种情况下自己找到这些文档。感谢您指出这一点。
    • 现在它是这样工作的,我的下一个任务是为该输入使用自动完成字段。
    • @DavidGleba,您可能需要一种不同且更复杂的方法来实现这一点,例如带有 django-select2 之类的选择小部件的自定义模型表单。看看这个@Fedor response to this questionselect2 documentation
    猜你喜欢
    • 2022-11-08
    • 2011-12-24
    • 2021-06-20
    • 2012-08-23
    • 2019-08-12
    • 2011-06-26
    • 2011-07-07
    • 2016-11-21
    • 2021-03-01
    相关资源
    最近更新 更多