【问题标题】:Custom Django Model Managers giving error when trying to use it自定义 Django 模型管理器在尝试使用时出错
【发布时间】:2023-04-07 08:29:01
【问题描述】:

我正在尝试编写一个简单的模型管理器来过滤特定字段。

我有一个看起来像这样的模型:

    """Model definition for Period."""
    year = models.ForeignKey(Year, on_delete=models.PROTECT)
    name = models.CharField(max_length=50)
    active = models.BooleanField(default=False)

    objects = models.Manager()
    active_year_periods = PeriodManager().active_year_periods()

我的期间经理看起来像这样:

class PeriodManager(models.Manager):
    """
    The manager for Period objects
    """

    def active_year_periods(self):
        """
        Gets the Period objects for the active year

        Returns:
            Period<Queryset> -- Periods for an active year
        """
        return super().get_queryset().filter(year__active=True)

我写了一些简单的东西来测试这个特定的管理器,但是遇到了一个我不确定它意味着什么的错误:

  File "/dir/path/myapp/models.py", line 44, in <module>
    class Period(models.Model):
  File "/dir/path/myapp/models.py", line 55, in Period
    active_year_periods = PeriodManager().active_year_periods()
  File "/dir/path/myapp/managers.py", line 19, in active_year_periods
    return self.get_queryset().filter(year__active=True)
  File "/dir/path/venv/lib/python3.7/site-packages/django/db/models/query.py", line 892, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/dir/path/venv/lib/python3.7/site-packages/django/db/models/query.py", line 910, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "/dir/path/venv/lib/python3.7/site-packages/django/db/models/sql/query.py", line 1290, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "/dir/path/venv/lib/python3.7/site-packages/django/db/models/sql/query.py", line 1318, in _add_q
    split_subq=split_subq, simple_col=simple_col,
  File "/dir/path/venv/lib/python3.7/site-packages/django/db/models/sql/query.py", line 1190, in build_filter
    lookups, parts, reffed_expression = self.solve_lookup_type(arg)
  File "/dir/path/venv/lib/python3.7/site-packages/django/db/models/sql/query.py", line 1049, in solve_lookup_type
    _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
  File "/dir/path/venv/lib/python3.7/site-packages/django/db/models/sql/query.py", line 297, in get_meta
    return self.model._meta
AttributeError: 'NoneType' object has no attribute '_meta'

这个错误在我的测试运行之前就开始了 - 我的测试目前是失败的,但它甚至不会因为那个错误而失败。

这是我的测试:

class TestPeriodManager(TestCase):
    """
    Test cases for the Period Manager
    """
    def setUp(self):
        pass    

    def test_active_year_periods_returns_correct_amount(self):
        """
        Test that the PeriodManager active_year_periods method returns
        appropriate amount of Periods
        """
        # periods_in_active_year = swm.Period.active_year_periods
        # print(periods_in_active_year)
        self.assertTrue(False)

任何想法为什么我可能会遇到这个问题?我是不是搞错了?

我正在尝试使用自定义管理器方法,因此最终我可以在需要时传递参数以进行额外过滤。

【问题讨论】:

    标签: python django django-models django-managers


    【解决方案1】:

    您需要将active_year_periods(您的自定义管理器)分配给管理器类,而不是方法:

    models.py

    objects = models.Manager()
    active_year_periods = PeriodManager()
    

    【讨论】:

    • 我不敢相信我错过了那个明显的东西。啊!旁注:命名经理是否有“最佳实践”?只是将自定义经理称为“经理”有什么问题,所以你会喜欢 Object.managers.some_function() 并且你可以清楚地看到发生了什么?
    • 对此没有官方约定,但我通常在名称后附加一个"_objects" 后缀(如foo_objects),以更清楚地表明它是经理。但是,我不推荐通用术语(如managers),因为它们可能会与 django 内容发生冲突。
    • 如果您计划将此管理器 only 添加到 filter 某些对象,您可能会发现另一件有用的事情是覆盖 initial 查询集(勾选docs),这样就不需要在manager之后再次调用active_year_periods方法了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-27
    • 1970-01-01
    • 2011-04-20
    • 1970-01-01
    • 2013-05-12
    • 2021-12-13
    相关资源
    最近更新 更多