Django:如何编写models.py

时间:2011-06-30 15:10:42

标签: django django-models django-admin

在应用程序中我有Post模型。在管理员面板中,我想只有一个条目 - “帖子”,其中一个链接可以添加帖子。在admin中的帖子列表中,我希望看到所有帖子。

所有帖子都有标题,内容和其他基本字段。

由于帖子来源,帖子可能有不同的字段。

Sources:

--- First
--- Second
--- Third
--- ......

例如,发布第一个来源 必须 的帖子有投票(但没有类别)。包含第二个来源 必须 的帖子属于类别分支#1中的类别(但没有轮询)。具有第三个来源的帖子可能有图像字段(但没有类别,也没有民意调查)等等。

Category branch #1

--- cb1_first
--- cb1_second
--- cb1_third

Category branch #....

--- cb2_first
--- cb2_second
--- cb2_third

所以,在Post add-page中我想写标题,内容,其他基本的东西,而不是我选择Source并且由于选择其他字段出现(对于第一个来源,它是Poll,第二个 - Category分类中的类别#1等等。

如果我制作基类Post,然后用其他类扩展它,我会在SQL中获得额外的表和应用程序管理员中的许多项目(即添加基本帖子,添加视频帖子,添加民意调查帖子,添加帖子与类别分支#2 ...)

寻求建议,如何组织此类申请。

2 个答案:

答案 0 :(得分:1)

这就是为什么我强烈反对在数据库级别使用null = False进行验证的原因。制作单个Post模型,其中包含任何类型的帖子可以包含的所有字段,但不强制要求模型(blank=True, null=True)。

然后,在您的表单上验证是否需要一个或哪个字段等,特别是在处理Admin时的ModelForms。

如果在一个实例中需要某个字段,则可以使用以下命令强制执行:

class MyModelForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(MyModelForm, self).__init__(*args, **kwargs)

        if self.instance.source == 'first':
            self.fields['poll'].required = True

然后,为了仅显示应根据源显示的实际字段,您可以为此处理一些JavaScript,或者实际上可以使用ModelAdmin.get_fieldsets()明确地将其从管理员中排除。因此,基本上这个过程就是:

class MyModelAdmin(admin.ModelAdmin):
    ...
    fieldsets = (
        (None, { 'fields': ('common_field_1', 'common_field_2', 'common_field_3',),
    )
    poll_fieldsets = (
        (None, { 'fields': ('common_field_1', 'common_field_2', 'common_field_3', 'poll',),
    )

    def get_fieldsets(self, request, obj=None):
        if obj and obj.source == 'first':
            return self.poll_fieldsets
        else:
            return super(MyModelAdmin, self).get_fieldsets(request=request, obj=obj)

答案 1 :(得分:0)

首先创建一个模型,其中包含帖子所需的基本字段(例如Post模型)。然后,您可以为源 - Source模型创建模型。 Post模型应该有一个外键,表示创建它的源。 Source模型应包含一个字段,用于存储要实例化的模型名称,以便存储具有给定源的帖子的其他字段。然后为您需要的每个附加字段集创建所有模型,每个模型应具有Post模型的外键字段。例如,您可以使用Poll的外键创建Post模型。

在对此类数据建模后,您只需引用Source模型即可在创建帖子和检索帖子时解析所有字段类型。