首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在django中避免模型字段的新实例化

在django中避免模型字段的新实例化
EN

Stack Overflow用户
提问于 2016-07-06 23:51:00
回答 1查看 66关注 0票数 1

我有一个带有自定义模型字段的模型表单。

代码语言:javascript
复制
class UserModelChoiceField(forms.ModelChoiceField):
    def label_from_instance(self, obj):
         return obj.get_full_name()

class TaskForm(forms.ModelForm):
    originator = UserModelChoiceField(queryset=User.objects.all().order_by('first_name'),widget=forms.Select(attrs={'class':'form-control'}))

    class Meta:
        model = Task
        fields = ['originator']

我的阅读表明,以这种方式处理我的字段将覆盖来自模型的任何信息(例如,是否需要它),因为它正在从我的定义中实例化它,而不是增强模型的字段。

看来,为了尽量减少对这样的字段的修改,我应该与init交互(见下文)。

代码语言:javascript
复制
def __init__(self,*args, **kwargs):
    super(TaskForm, self).__init__(*args, **kwargs)

    self.fields['originator'].queryset=User.objects.all().order_by('first_name')
    self.fields['originator'].widget = forms.Select(attrs={'class':'form-control'})

假设上面的内容是正确的,我理解如何做queryset和小部件。我的问题是我该如何使用那个定制的选项场。此外,我甚至不确定这是否是这样做的方式,因为它似乎有点麻烦。

EN

Stack Overflow用户

回答已采纳

发布于 2016-07-09 16:11:43

呃..。我记得我有这个问题,没有找到一个内置的或惯用的解决方案。我没有想出比这个装饰师更好的解决方案(是的,这是生产代码):

代码语言:javascript
复制
def model_generated(model):
    """Generate form fields from model fields

    Purpose:
        This decorator lets you have form field attributes like
        `max_length` copied over from a model field while being DRY.

    Usage:
        Decorate a form class with this decorator and set MODEL_GENERATED_FIELDS
        to a list of attribute names you would like to be generated.

    Limitations:
        - Currently, this decorator only supports CharFields.
    """

    def decorator(cls):

        for field_name in cls.MODEL_GENERATED_FIELDS:
            model_field = model._meta.get_field(field_name)

            model_field_type = type(model_field)
            if model_field_type == django_models.CharField:
                form_field_type = forms.CharField
                attributes = {  # (form_attribute, model_attribute, processor)
                    ('label', 'verbose_name', None),
                    ('max_length', None, None),
                    ('min_length', None, None),
                    ('required', 'blank', lambda value: not value),
                }
            else:
                # (Maybe one day this decorator will support more types of fields.)
                raise ValueError("Unknown type of model field: {}".format(model_field_type))

            kwargs = {}
            for form_attribute, model_attribute, processor in attributes:
                if model_attribute is None:
                    model_attribute = form_attribute
                if processor is None:
                    processor = lambda value: value

                if hasattr(model_field, model_attribute):
                    kwargs[form_attribute] = processor(getattr(model_field, model_attribute))

            form_field = form_field_type(**kwargs)
            setattr(cls, field_name, form_field)

            # Register field since we're monkey-patching
            # (Django's meta-class hackery to detect fields only runs the first time the class is declared.)
            cls.base_fields[field_name] = form_field

        return cls

    return decorator

所以,举个例子,我会:

代码语言:javascript
复制
 class Team(models.Model):
    name = models.CharField(max_length=30, unique=True,
                            verbose_name="Team Name")
    passphrase = models.CharField(max_length=30,
                                  verbose_name="Passphrase")
    ...

以及:

代码语言:javascript
复制
@model_generated(models.Team)
class TeamJoiningForm(forms.Form):
    MODEL_GENERATED_FIELDS = ('name', 'passphrase')
    ...

您可以根据自己的特定需求调整和扩展model_generated装饰器。抱歉的。

票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38235623

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档