Django - 过滤外键查找数据

时间:2015-07-03 16:31:37

标签: django filter

在Django中,如果当前行的值如何,如何返回过滤的外键数据PLUS当前行的值? 是不是在那个过滤的数据?

例如:

模型 - 如果我有以下Django(psuedo)模型

class Record(models.Model):    
    field1
    field2
    ...
    name = models.ForeignKey(Names)

class Names(models.Model):    
    name = models.CharField()
    active = models.BooleanField()

数据 - 名称表格中的一行可以随时设置为有效或无效,例如:

name           active 
LegacyName1    N 
LegacyName2    N 
ShinyNewName1  Y 
ShinyNewName2  Y 
ShinyNewName3  Y

表单 - 名称应显示在每个表单的列表框中,如下所示:

  • 添加记录 - >列出活动名称
  • 编辑记录 - > list active名称 PLUS 正在编辑的记录的名称
  • 显示记录 - >只显示当前值,不需要列表框

    然而,问题是当用户编辑一个名称不再有效的记录时。

    他们可能想要编辑其他记录详细信息(不一定是名称),但他们仍然希望看到 列表框中的当前名称以及其他可能的'活动'他们可以将其改为例如

    列表框条目应如下所示

  • LegacyName1(当前记录' s值,有效=' N')
  • ShinyNewName1
  • ShinyNewName2
  • ShinyNewName3

    但是' LegacyName1'没有出现,因为它不在活跃的'名称列表,即使它是当前记录的名称值。

    Django Way?

    Django建议:

    • 使用额外的Manager方法作为向模型添加“表级”功能的首选方法
    • “行级”功能的模型方法 - 作用于模型对象的单个实例的函数。

    我已经尝试了表级管理器方法,可以轻松返回所有活动的'通过过滤器命名:

    class NamesManager(models.Manager):        
        def get_query_set(self):
            return super(NamesManager, self).get_query_set().filter(active=True)
    

    但是,如果行的现有名称不活动,则将其从列表框中删除 - 这可能是预期的, 虽然不是我想要的。

    行级方法是正确的方法,因为此功能特定于单行,例如, "如果我的名字不在名单列表中,我想要添加它无论如何"但我无法弄清楚如何/在哪里适应这个?

    第三种选择可能是尝试使用Record' post_init'信号和第四种选择可能可能以某种方式修改“上下文”。 在它从视图传递回到表单之前,但这两种方法都可能感觉它们可能属于“fudged'横幅。

    有人可以建议首选的Django方法吗?或者我可能会以错误的方式思考这个问题?

  • 1 个答案:

    答案 0 :(得分:0)

    如果您在创建记录时只想显示活动名称,请编辑您的创建表单以获得以下内容:

    class CreateRecordForm(forms.ModelForm):
        name = ModelChoiceField(queryset=Name.objects.filter(active=True))
    

    在EditRecordForm上,您可以为名称字段引入一个干净的方法,以验证它是否仍处于活动状态。

    class EditRecordForm(forms.ModelForm):
        def clean_name(self):
            name = self.cleaned_data['name']
            if not Name.objects.filter(pk=name, active=True.exists():
                raise forms.ValidationError("The selected name is inactive. Please select a name that is active.")
            return name
    

    这也可以避免对ModelManager进行任何更改。