修改Crispy Forms的字符串表示形式

huangapple go评论48阅读模式
英文:

Change crispy forms string representation

问题

Crispy forms 使用由对象的类的__str__方法提供的对象的字符串表示形式:我需要更改这种行为(请帮助我)。

在我的 Crispy 表单中,CheckboxSelectMultiple() 字段中的选项的标签从对象的默认__str__方法中填充。对象的集合在包含 id 的列表中定义,使用这些 id,Crispy 调用__str__方法。

是否可以编写自定义的字符串表示形式(例如,作为类的@property)并告诉 Crispy 使用它呢?
如果可以,管道中的哪一点会提供最佳的编程实践(models/views/forms/template)?

this image is just a dummy example for better illustrating the problem
覆盖默认的__str__方法提供所需的标签(如帖子中建议的),但由于副作用而完全不可接受。

models.py

class School(models.Model):

	nice_name_for_forms = models.CharField(max_length=100)	
	
	@property
	def label_from_instance(self):
	    return '%s' % (self.nice_name_for_forms)

views.py

school_list = School.objects.all().values_list('id', flat=True)
form = MyForm(request.POST, school_list=school_list)

forms.py

class MyForm(forms.ModelForm):
	
	class Meta:
		model = MyForm
		fields = '__all__'		
		labels = {'schools' : 'My Schools'}
				
		widgets = {'schools' : forms.CheckboxSelectMultiple()}

	def __init__(self, *args, **kwargs):
		self.school_list = kwargs.pop('school_list')		
		super().__init__(*args, **kwargs)
		self.fields['schools'].queryset = self.fields['schools'].queryset.filter(id__in=self.school_list).distinct()

		self.helper = FormHelper()
		self.helper.use_custom_control = False
		self.helper.layout = Layout(
			Row(CheckboxAllFieldCompact('schools', wrapper_class='col-4 col-md-2'))

checkbox_all_field.html

<!-- crispy/checkbox_all_field.html -->
{% load crispy_forms_field %}
{% load i18n %}
<div id="div_checkbox_all_{{ field.html_name }}" class="no-form-control control-group {{ wrapper_class }}">
	<div class="controls" style="max-height:250px;overflow:auto">
		<label for="{{ field.name_for_label }}" class="label_title inline">{{ field.label }}</label>
		<br />
		<label class="block">
			<button id="check_all_{{ field.html_name }}" type="button" class="btn btn-default btn-sm" actif="false">{% translate 'Select all' %}</button>
		</label>
		{% crispy_field field %}
	</div>
</div>
英文:

Crispy forms use the string representation of objects provided by the str method of the objects' class: I need to change this behaviour (please, help me).

In my crispy form the labels of the choices in a CheckboxSelectMultiple() field populate from the default str method of the objects represented. The set of objects is defined in a list containing ids, with those ids crispy calls the str methods.

Is it possible to write a custom string representation (for instance as a class' @property) and tell crispy to use that instead?
If yes, which point in the pipeline would give the best programmer's practice (models/views/forms/template) ?

this image is just a dummy example for better illustrating the problem
Overriding the default str method provides the desired labelling (as suggested in this post) but is totally unacceptable because of side effects.

models.py

class School(models.Model):

	nice_name_for_forms = models.CharField(max_length=100)	
	
	@property
	def label_from_instance(self):
	    return &#39;%s&#39; % (self.nice_name_for_forms)

views.py

school_list = School.objects.all().values_list(&#39;id&#39;, flat=True)
form = MyForm(request.POST, school_list=school_list)

forms.py

class MyForm(forms.ModelForm):
	
	class Meta:
		model = MyForm
		fields = &#39;__all__&#39;		
		labels = {&#39;schools&#39; : &#39;My Schools&#39;}
				
		widgets = {&#39;schools&#39; : forms.CheckboxSelectMultiple()}

	def __init__(self, *args, **kwargs):
		self.school_list = kwargs.pop(&#39;school_list&#39;)		
		super().__init__(*args, **kwargs)
		self.fields[&#39;schools&#39;].queryset = self.fields[&#39;schools&#39;].queryset.filter(id__in=self.school_list).distinct()

		self.helper = FormHelper()
		self.helper.use_custom_control = False
		self.helper.layout = Layout(
			Row(CheckboxAllFieldCompact(&#39;schools&#39;, wrapper_class=&#39;col-4 col-md-2&#39;))

checkbox_all_field.html

&lt;!-- crispy/checkbox_all_field.html --&gt;
{% load crispy_forms_field %}
{% load i18n %}
&lt;div id=&quot;div_checkbox_all_{{ field.html_name }}&quot; class=&quot;no-form-control control-group {{ wrapper_class }}&quot;&gt;
	&lt;div class=&quot;controls&quot; style=&quot;max-height:250px;overflow:auto&quot;&gt;
		&lt;label for=&quot;{{ field.name_for_label }}&quot; class=&quot;label_title inline&quot;&gt;{{ field.label }}&lt;/label&gt;
		&lt;br /&gt;
		&lt;label class=&quot;block&quot;&gt;
			&lt;button id=&quot;check_all_{{ field.html_name }}&quot; type=&quot;button&quot; class=&quot;btn btn-default btn-sm&quot; actif=&quot;false&quot;&gt;{% translate &#39;Select all&#39; %}&lt;/button&gt;
		&lt;/label&gt;
		{% crispy_field field %}
	&lt;/div&gt;
&lt;/div&gt;

答案1

得分: 0

以下是代码部分的翻译:

In my opinion, the cleanest way for changing the string representation of objects used in crispy forms' fields involves writing a @staticmethod label_for_schools in forms.py within the relevant class:

#forms.py

class MyForm(forms.ModelForm):

class Meta:

    model = MyForm
    fields = '__all__'      
    labels = {'schools' : 'My Schools';}
            
    widgets = {'schools' : forms.CheckboxSelectMultiple()}

@staticmethod
def label_for_schools(self):
	if self.nice_name_for_forms:
        return '%s' % (self.nice_name_for_forms)

def __init__(self, *args, **kwargs):
    self.school_list = kwargs.pop('school_list')        
    super().__init__(*args, **kwargs)
    self.fields['schools'].queryset = self.fields['schools'].queryset.filter(id__in=self.school_list).distinct()

    self.helper = FormHelper()
    self.helper.use_custom_control = False
    self.helper.layout = Layout(
        Row(CheckboxAllFieldCompact('schools', wrapper_class='col-4 col-md-2'))
英文:

In my opinion, the cleanest way for changing the string representation of objects used in crispy forms' fields involves writing a @staticmethod label_for_schools in forms.py within the relevant class:

#forms.py

class MyForm(forms.ModelForm):

    class Meta:

        model = MyForm
        fields = &#39;__all__&#39;      
        labels = {&#39;schools&#39; : &#39;My Schools&#39;}
                
        widgets = {&#39;schools&#39; : forms.CheckboxSelectMultiple()}

    @staticmethod
	def label_for_schools(self):
		if self.nice_name_for_forms:
            return &#39;%s&#39; % (self.nice_name_for_forms)

    def __init__(self, *args, **kwargs):
        self.school_list = kwargs.pop(&#39;school_list&#39;)        
        super().__init__(*args, **kwargs)
        self.fields[&#39;schools&#39;].queryset = self.fields[&#39;schools&#39;].queryset.filter(id__in=self.school_list).distinct()

        self.helper = FormHelper()
        self.helper.use_custom_control = False
        self.helper.layout = Layout(
            Row(CheckboxAllFieldCompact(&#39;schools&#39;, wrapper_class=&#39;col-4 col-md-2&#39;))

huangapple
  • 本文由 发表于 2023年2月16日 04:51:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75465322.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定