使用 Camelot 指定备选 EntityAdmin

50 阅读2分钟

使用 Camelot 框架时,模型(Entity 的子类)使用嵌套类(EntityAdmin 的子类)定义,该嵌套类定义各种 gui 属性,如布局和其他小部件。文档表明可以定义多个 EntityAdmin,然后由调用模型指定:

在关系字段的情况下,指定用于可视化关系另一端的管理类。默认为目标类的默认管理类。这可用于使 one2many 小部件中的表格视图不同于同一对象默认的表格视图。 Camelot:字段属性手册页

我似乎无法弄清楚所需的语法。作为一个案例研究,是否有谁可以帮助我找出如何使用包中的“camelot-example”来做到这一点?(Camelot 13.04.13,Python 2.7.6) 这是一个示例代码:

from sqlalchemy.schema import Column
from sqlalchemy.types import Unicode, Integer

from camelot.admin.entity_admin import EntityAdmin
from camelot.core.orm import Entity, ManyToOne, OneToMany
import camelot.types


class Company(Entity):
    __tablename__ = 'company'

    name = Column(Unicode())
    city = Column(Unicode())
    employees = OneToMany('Employee')

    def __unicode__(self):
        return self.name or ''

    class Admin(EntityAdmin):
        verbose_name = 'Company'
        verbose_name_plural = 'Companies'
        list_display = ['name', 'city', 'employees']
        field_attributes = {'employees': {'create_inline': True},
                                          'admin': 'AlternativeAdmin'}


class Employee(Entity):
    __tablename__ = "employee"

    name = Column(Unicode())
    age = Column(Integer())
    company = ManyToOne('Company')

    def __unicode__(self):
        return self.name or ''

    class Admin(EntityAdmin):
        verbose_name = 'Employee'
        list_display = ['name', 'age', 'company']

    class AlternativeAdmin(EntityAdmin):
        verbose_name = 'Employee'
        list_display = ['name']

注意:

Company.Admin.field_attributes 中的“admin” “AlternativeAdmin”类

这段代码运行时没有错误,但不能按预期工作。公司表单显示一个显示姓名、年龄和公司的员工子表单。它应该只显示公司。我曾尝试使用以下方法来设置“admin”值: ‘AlternativeAdmin’ AlternativeAdmin ‘Employee.AlternativeAdmin’ Employee.AlternativeAdmin

取消注释时收到的错误是: NameError:名称“AlternativeAdmin”未定义 我是自认的 Python 初学者,我怀疑更好地理解 Python 可以帮助我解决这个问题。 我通过万能的八号球(Google)找到了这个:一个论坛海报说(原文如此),“愚蠢的我,我坚持让备用管理员类与原始类一样是内部类。一旦取消嵌套,它就可以工作了。”他说的是这段代码:

class A(Entity):
     ...
     class Admin(EntityAdmin):
          ...
     class AdminEmbedded(EntityAdmin):
         ...

class B(Entity):
     classA = OneToMany(...)
     ...
     class Admin(EntityAdmin):
          field_attributes = dict(classA=dict(admin=A.AdminEmbedded???))

不幸的是,他的语法和/或拼写让人很难辨别他的意思。此外,我非常确定那里应该有一些引号。

2、解决方案 我想通了。答案让我感到惊讶——我把 AlternativeAdmin 类定义保留在它下面,在我取消嵌套之后才调用它。一旦我将其移至上方,它就能正常工作。 这是我问题中示例的完整修复版本:

from sqlalchemy.schema import Column
from sqlalchemy.types import Unicode, Integer

from camelot.admin.entity_admin import EntityAdmin
from camelot.core.orm import Entity, ManyToOne, OneToMany
import camelot.types


class AlternativeAdmin(EntityAdmin):
    verbose_name = 'Employee'
    list_display = ['name']


class Company(Entity):
    __tablename__ = 'company'

    name = Column(Unicode())
    city = Column(Unicode())
    employees = OneToMany('Employee')

    def __unicode__(self):
        return self.name or ''

    class Admin(EntityAdmin):
        verbose_name = 'Company'
        verbose_name_plural = 'Companies'
        list_display = ['name', 'city', 'employees']
        field_attributes = {'employees': {'create_inline': True,
                                          'admin': AlternativeAdmin}}


class Employee(Entity):
    __tablename__ = "employee"

    name = Column(Unicode())
    age = Column(Integer())
    company = ManyToOne('Company')

    def __unicode__(self):
        return self.name or ''

    class Admin(EntityAdmin):
        verbose_name = 'Employee'
        list_display = ['name', 'age', 'company']