【问题标题】:Django - filter foreign key lookup dataDjango - 过滤外键查找数据
【发布时间】:2015-07-03 16:31:36
【问题描述】:

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

例如:

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

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

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

数据 - Names 表中的一行可以随时设置为活动或非活动,例如:

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

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

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

    但是,当用户编辑名称不再处于活动状态的记录时,问题就出现了。

    他们可能想要编辑其他记录详细信息(不一定是名称),但他们仍想查看 列表框中的当前名称以及其他可能的“活动”选项,他们可以将其更改为例如

    列表框条目应该像这样显示

  • LegacyName1(当前记录的值,活动 ='N')
  • 闪亮的新名字1
  • 闪亮的新名字2
  • 闪亮的新名字3

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

    Django 方式?

    Django 推荐:

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

    我已经尝试过表级管理器方法,并且可以通过过滤器轻松返回所有“活动”名称:

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

    但是,如果行的现有名称未处于活动状态,这会将其从列表框中剔除 - 这可能是意料之中的, 虽然不是我想要的。

    行级方法感觉是正确的方法,因为此功能特定于单行,例如, “如果我的名字不在名字列表中,我还是想添加它”但我不知道如何/在哪里适合这个?

    第三个选项可能是尝试使用 Record 'post_init' 信号,第四个选项可能是以某种方式修改“上下文” 在将其从视图传递回表单之前,但这两种方法都感觉可能属于“捏造”的旗帜。

    任何人都可以建议首选的 Django 方法吗?还是我想错了?

  • 【问题讨论】:

      标签: django filter


      【解决方案1】:

      如果您希望在创建记录时仅显示活动名称,请编辑您的创建表单以包含以下内容:

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

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

      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 的任何更改。

      【讨论】:

        猜你喜欢
        • 2019-10-08
        • 1970-01-01
        • 2021-06-06
        • 1970-01-01
        • 2020-09-07
        • 2012-01-23
        • 1970-01-01
        • 2018-03-04
        • 2023-03-11
        相关资源
        最近更新 更多