【问题标题】:django custom field saves but not visualizedjango 自定义字段保存但不可视化
【发布时间】:2023-03-28 19:30:01
【问题描述】:

我创建了一个字段来保存工作日,在这样的模型中使用 (models.py):

from myfields import *
from django.db import models

class MyModel(models.Model):
    weekdays = WeekdayField()

我存储表单声明的文件是myfields.py,是这个:

from django.db import models
from django import forms

class Weekdays(object):
    CHOICES = (
        (1, "Monday"),
        (2, "Tuesday"),
        (4, "Wednesday"),
        (8, "Thursday"),
        (16, "Friday"),
        (32, "Saturday"),
        (64, "Sunday"),
        )
    MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY = [2**i for i in range(0,7)]
    del i

    def __init__(self, value=0):
        self.raw = value

    def __add__(self, other):
        return Weekdays(self.raw | other)

    def __sub__(self, other):
        return Weekdays(self.raw & (-1 ^ other))

    def __unicode__(self):
        ret = []
        for ele in Weekdays.CHOICES:
            if (self.raw & ele[0]) >> ele[0] == 1:
                ret.append(ele[1])
        return ",".join(ret)

    def __iter__(self):
        ret = []
        for ele in Weekdays.CHOICES:
            if (self.raw & ele[0]) >> ele[0] == 1:
                ret.append(ele)
        return iter(ret)

    def __len__(self):
        i = 0
        for n in range(7):
            if (self.raw & n) >> n == 1:
                i += 1
        return i



class WeekdayField(models.Field):
    description = "Multiple select of weekdays"

    __metaclass__ = models.SubfieldBase

    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = 3
        super(WeekdayField, self).__init__(*args, **kwargs)

    def to_python(self, value):
        if isinstance(value, int):
            return [ wd for wd in Weekdays(value) ]
        if isinstance(value, Weekdays):
            return value
        if isinstance(value, list): #list of weekstay
            wd = Weekdays()
            for val in value:
                wd += int(val)
            return wd

    # PY to DB
    def get_prep_value(self, value):
        return value.raw

    def formfield(self, **kwargs):
        defaults = {'form_class': WeekdayFormField}
        defaults.update(kwargs)
        return super(WeekdayField, self).formfield(**defaults)

    def get_internal_type(self):
        return "IntegerField"


class WeekdayFormField(forms.MultipleChoiceField):
    def __init__(self, *args, **kwargs):
        if 'choices' not in kwargs:
            kwargs['choices'] = Weekdays.CHOICES
        kwargs.pop('max_length', None)
        if 'widget' not in kwargs:
            kwargs['widget'] = forms.widgets.CheckboxSelectMultiple
        super(WeekdayFormField, self).__init__(*args, **kwargs)


    def clean(self, value):
        super(WeekdayFormField, self).clean(value)
        possible_values = [ str(x[0]) for x in Weekdays.CHOICES ]
        for v in value:
            if not v in possible_values:
                raise forms.ValidationError("Day not valid")
        return value

使用这个我可以通过 Django Admin 创建和删除元素,但是当我修改一个值时,我看不到我之前存储的值。我查看了数据库并正确存储了值。

在修改期间如何让我看到 Django Admin 上的当前值是什么?

【问题讨论】:

    标签: python django django-forms django-admin django-models


    【解决方案1】:

    我有办法! Weekdays.__unicode__()Weekdays.__iter__() 方法的实现是错误的。

    最后我还更改了下面报告的两种方法,WeekdayField

    #Class-type
    class Weekdays(object):
        ...
    
        def __unicode__(self): # Request for the matching
            ret = []
            for i,ele in enumerate(Weekdays.CHOICES):
                if (self.raw & ele[0]) >> i == 1:
                    ret.append(unicode(ele[0]))
            return ','.join(ret)
    
        def __iter__(self):
            for i,ele in enumerate(Weekdays.CHOICES):
                if (self.raw & ele[0]) >> i == 1:
                    yield Weekdays(ele[0])
    
    
    #Field to include in the model
    class WeekdayField(models.Field):
        ...
    
        # DB to PY
        def to_python(self, value):
            if isinstance(value, int):
                return [ wd for wd in Weekdays(value) ]
            if isinstance(value, unicode):
                return [ wd for wd in Weekdays(int(value)) ]
            if isinstance(value, Weekdays):
                return value
            if isinstance(value, list): #list of Weekdays
                wd = []
                for val in value:
                    wd += self.to_python(val)
                return wd
    
        #PY to DB
        def get_prep_value(self, value):
            if isinstance(value, Weekdays):
                return value.raw
            if isinstance(value, list):
                sum_raw = 0
                for val in value:
                    sum_raw += self.get_prep_value(val)
                return sum_raw
    

    我希望这对某人有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-27
      • 1970-01-01
      • 1970-01-01
      • 2020-12-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多