Django admin:根据模型显示字段

问题描述 投票:0回答:1

我正在开发一个登陆页面类型网站的后端,在项目开发过程中我遇到了很多模型

...the rest of the code
class FunctionalBlock(models.Model):
    title = models.CharField(max_length=255,blank=True, null=True)
    subtitle = models.CharField(max_length=255,blank=True, null=True)
    icon = models.ForeignKey(to='Image', on_delete=models.SET_NULL, blank=True, null=True,related_name='function_block_icon')
    image = models.ForeignKey(to='Image', on_delete=models.SET_NULL, blank=True, null=True,related_name='function_block_image')
    form = models.ForeignKey(to='FormNVA', on_delete=models.SET_NULL, blank=True, null=True,related_name='function_block')
    buttons = models.ManyToManyField(to='Buttons',blank=True, null=True)
    time = models.DateTimeField(blank=True, null=True)
    section = models.ForeignKey(to='Section', on_delete=models.CASCADE,related_name='function_block')
    text = models.TextField(blank=True, null=True)
class Section(models.Model):
    title = models.CharField(max_length=255, blank=True, null=True)
    subtitle = models.CharField(max_length=255, blank=True, null=True)
    background = models.ForeignKey(to='Image', on_delete=models.SET_NULL, blank=True, null=True,related_name='section')

# PAGE
class PageHome(models.Model):
    title = models.CharField(max_length=255)
    language = models.ForeignKey(to='Language', on_delete=models.SET_NULL, blank=True, null=True)
    head = models.OneToOneField(to='Head', on_delete=models.SET_NULL, blank=True, null=True)
    body = models.OneToOneField(to='Body', on_delete=models.SET_NULL, blank=True, null=True, related_name='page_home')

    objects = models.Manager()
    objects_lang = LanguageManager()

    def __str__(self):
        return f'{self.title}'

class PageServices(models.Model):
    title = models.CharField(max_length=255)
    language = models.ForeignKey(to='Language', on_delete=models.SET_NULL, blank=True, null=True)
    head = models.OneToOneField(to='Head', on_delete=models.SET_NULL, blank=True, null=True)
    body = models.OneToOneField(to='Body', on_delete=models.SET_NULL, blank=True, null=True, related_name='page_services')


    objects = models.Manager()
    objects_lang = LanguageManager()

class PageCareer(models.Model):
    title = models.CharField(max_length=255)
    language = models.ForeignKey(to='Language', on_delete=models.SET_NULL, blank=True, null=True)
    head = models.OneToOneField(to='Head', on_delete=models.SET_NULL, blank=True, null=True)
    body = models.OneToOneField(to='Body', on_delete=models.SET_NULL, blank=True, null=True, related_name='page_career')


    objects = models.Manager()
    objects_lang = LanguageManager()

# BODY

class Body(models.Model):


    class FieldSets(Enum):
        HOME =['services','options','become_part_of_us','cta_text','numbers','partners','questions']
        SERVICES = ['services']

    # Home
    services = models.ForeignKey(to='Section',on_delete=models.SET_NULL, blank=True, null=True, related_name='body_home_services')
    options = models.ForeignKey(to='Section',on_delete=models.SET_NULL, blank=True, null=True, related_name='body_home_options')
    become_part_of_us = models.ForeignKey(to='Section',on_delete=models.SET_NULL, blank=True, null=True, related_name='body_home_become_part_of_us')
    cta_text = models.ForeignKey(to='Section',on_delete=models.SET_NULL, blank=True, null=True, related_name='body_home_cta_text')
    numbers = models.ForeignKey(to='Section',on_delete=models.SET_NULL, blank=True, null=True, related_name='body_home_numbers')
    partners = models.ForeignKey(to='Section',on_delete=models.SET_NULL, blank=True, null=True, related_name='body_home_partners')
    questions = models.ForeignKey(to='Section',on_delete=models.SET_NULL, blank=True, null=True, related_name='body_home_questions')
    # Services
    news = models.ForeignKey(to='Section',on_delete=models.SET_NULL, blank=True, null=True, related_name='body_home_news')

如您所见,我为每个页面都有一个单独的模型,同样,我为每个页面模型都有一个单独的主体模型,为了让它们减少,我将字段汇总在一个表中,即主体,在这里我面临一个问题,即当我在管理面板中创建任何页面,当我单击管理面板中的添加正文并出现弹出窗口时,我想过滤与此页面模型专门相关的字段

管理面板

作为解决方案,我考虑传递 url 参数并使用 get_fieldsets 来过滤字段,但我无法实现我想要的。

@admin.register(Body)
class BodyAdmin(admin.ModelAdmin):
    def get_fieldsets(self, request, obj):
        model = self.model
        related_model = self.opts.related_objects[0].related_model
        fieldsets = copy.deepcopy(super().get_fieldsets(request, obj))

        if related_model is PageHome:
             fieldsets[0][1]['fields'] = model.FieldSets.HOME.value
        if related_model is PageServices:
            fieldsets[0][1]['fields'] = model.FieldSets.SERVICES.value

        return fieldsets

我为登陆页面创建后端的方法是否正确?如果是,是否可以在正文中实现字段过滤? 预先感谢

我尝试传递查询参数来解决这个问题,我还在 BodyAdmin 中寻找调用 Page...Admin 的依赖关系,但这两个选项都不成功

django django-models django-views django-forms django-admin
1个回答
0
投票

这并不能回答你的问题,但我认为它可能会改善你的模型结构。

既然

PageHome
PageService
PageCareer
相似并且具有完全相同的字段,那么为什么不使用一个带有额外字段的模型来区分页面类型。然后使用代理功能和每个自定义管理器,如下所示:

创建你的经理:

# Base manager
class PageManager(models.Manager):
    class PageType(models.TextChoices):
        HOME = 'H', _('Home')
        SERVICE = 'S', _('Service')
        CAREER = 'C', _('Career')

    # default page type
    PAGE_TYPE = PageType.SERVICE

    def get_queryset(self, *args, **kwargs):
        return (
            super().get_queryset(*args, **kwargs)
            .filter(type=self.PAGE_TYPE)
        )

    def save(self, *args, **kwargs):
        if not self.pk:
            self.type = self.PAGE_TYPE
        return super().save(*args, **kwargs)

# Page managers
class HomeManager(PageManager):
    PAGE_TYPE = PageManager.PageType.HOME

class ServiceManager(PageManager):
    PAGE_TYPE = PageManager.PageType.SERVICE

class CareerManager(PageManager):
    PAGE_TYPE = PageManager.PageType.CAREER

至于您的型号:

# Models
class Page(models.Model):
    title = models.CharField(max_length=255)
    type = models.CharField(max_length=1, choices=PageManager.PageType.choices, default=PageManager.PAGE_TYPE)
    language = models.ForeignKey(to='Language', on_delete=models.SET_NULL, blank=True, null=True)
    head = models.OneToOneField(to='Head', on_delete=models.SET_NULL, blank=True, null=True)
    body = models.OneToOneField(to='Body', on_delete=models.SET_NULL, blank=True, null=True, related_name='page_home')

    objects = PageManager()
    objects_lang = LanguageManager()

    def __str__(self):
        return f'{self.title}'


class PageHome(Page):
    class Meta:
        proxy = True

    objects = HomeManager()

class PageServices(Page):
    class Meta:
        proxy = True

    objects = ServiceManager()

class PageCareer(Page):
    class Meta:
        proxy = True

    objects = CareerManager()

然后您可以像以前一样使用

PageHome
PageService
PageCareer
。因为它们就像一个具有自己的表和字段的独立模型,但实际上并非如此。他们使用带有自定义过滤器的
Page
模型。

希望有帮助

© www.soinside.com 2019 - 2024. All rights reserved.