You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django 2.0中django-recurrence显示文本字段而非正确字段的问题

解决django-recurrence的RecurrenceField在Django2.0中的兼容性问题

看起来你遇到的问题是由于Django 2.0对旧API的移除和机制调整导致的,我帮你梳理关键修改点,让这个字段能在Django2.0+正常工作:

1. 替换django.utils.six依赖

Django2.0彻底移除了对django.utils.six的支持(因为不再兼容Python2),原来的字符串类型判断需要调整:

# 替换这行旧代码:
# from django.utils.six import string_types
# 改成Python3原生的字符串类型定义:
string_types = str

2. 移除Creator相关代码

Creator类是旧版Django中配合SubfieldBase的兼容层,而Django1.10+已经移除了SubfieldBase,现在字段的自动转换机制已经完善,不需要再手动绑定Creator。删掉contribute_to_class方法里的这一行:

setattr(cls, self.name, Creator(self))

3. 可选:清理South相关代码

Django2.0已经自带成熟的迁移系统,South早已被淘汰,你可以直接删掉整个try-except块(如果不需要兼容极旧的Django版本):

# 删掉这段无用代码:
# try:
#     from south.modelsinspector import add_introspection_rules
#     add_introspection_rules([], [
#         "^recurrence\.fields\.RecurrenceField",
#     ])
# except ImportError:
#     pass

修改后的完整代码

from django.db.models import fields
import recurrence
from recurrence import forms

# 替换原有的string_types导入
string_types = str

class RecurrenceField(fields.Field):
    """Field that stores a `recurrence.base.Recurrence` to the database."""
    def __init__(self, include_dtstart=True, **kwargs):
        self.include_dtstart = include_dtstart
        super().__init__(**kwargs)

    def get_internal_type(self):
        return 'TextField'

    def to_python(self, value):
        if value is None or isinstance(value, recurrence.Recurrence):
            return value
        value = super().to_python(value) or ''
        return recurrence.deserialize(value, self.include_dtstart)

    def from_db_value(self, value, *args, **kwargs):
        return self.to_python(value)

    def get_prep_value(self, value):
        if not isinstance(value, string_types):
            value = recurrence.serialize(value)
        return value

    def contribute_to_class(self, cls, *args, **kwargs):
        super().contribute_to_class(cls, *args, **kwargs)
        # 移除了Creator绑定逻辑

    def value_to_string(self, obj):
        return self.get_prep_value(self._get_val_from_obj(obj))

    def formfield(self, **kwargs):
        defaults = {
            'form_class': forms.RecurrenceField,
            'widget': forms.RecurrenceWidget,
        }
        defaults.update(kwargs)
        return super().formfield(**defaults)

为什么这些修改能解决问题?

  • Django2.0完全放弃Python2支持,six库的依赖已经多余,直接用Python3原生的str类型即可完成字符串判断。
  • Creator是旧版Django的兼容产物,现在Django的字段系统会自动调用to_python和from_db_value处理值转换,手动绑定Creator反而会引发逻辑冲突。
  • South的代码在现代Django环境中毫无作用,清理后能避免不必要的导入错误。

内容的提问来源于stack exchange,提问作者questnofinterest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:20:45