Using django crispy-forms wrap to wrap multiple properties - python

I have a form with lots of repetition and I want to use the wrap function of django crispy forms to reduce this. This is the form as it stands:
class MyForm(ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.layout = Layout(
Row(Field(PrependedText('field1', 'Field1title', wrapper_class='col-12 stretchprepend')),
title = self.base_fields['field1'].help_text, data_bs_toggle='tooltip',
data_bs_placement='bottom', data_html="true"),
#fields 2-29
Row(Field(PrependedText('field30', 'Field30title', wrapper_class='col-12 stretchprepend')),
title = self.base_fields['field1'].help_text, data_bs_toggle='tooltip',
data_bs_placement='bottom', data_html="true")
)
CHOICES = [tuple([x,x]) for x in range(1,8)]
help_text = {'field1': ''''help text for field 1''' #etc for other fields)
field1 = IntegerField( label='Field1title', widget=Select(choices=CHOICES), help_text=help_text['field1'])
# Repeat up to field 30
class Meta:
model = mymodel
fields = ['field1',...,'field30']
I can get wrap to generate some aspects of the form like so:
self.helper.layout('field1'...'field30')
self.helper[:].wrap(Field, wrapper_class='col-12 stretchprepend')
I cant' seem to get it to work to include all the other aspects e.g. PrependedText, title, data_bs_toggle etc Please could anyone advise?

Related

Select2 more filter in Django

i have this code below, where i'm using Select2 in my select component, it's working fine, as i'm writing it's looking, but i've already searched the internet to find examples of how to customize the query set that runs in the widget, some help ?
select2 works very well
class ConsumidorWidget(s2forms.ModelSelect2Widget):
search_fields = [
"nome__icontains",
"email__icontains",
]
class ConsumoForm(forms.ModelForm):
class Meta:
model = Consumo
fields = ('id', 'consumidor', 'mesconsumo', 'anoconsumo', 'valorapagar', 'valorhidrometro',
'dataleitura', 'datamissao', 'datavencimento', 'foipago',)
exclude = ('bairro',)
mesconsumo = forms.ChoiceField()
widgets = {
"consumidor": ConsumidorWidget,
}
Use ModelChoiceField:
consumidor = forms.ModelChoiceField(
queryset=Consumo.objects.all(),
widget=ConsumidorWidget)
Or you can try overriding the __init__ method:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['consumidor'].queryset = Consumo.objects.all()

Can I assign queryset to django form in views? [duplicate]

I am creating my form in Form.py like this:
class pdftabelModelForm(forms.ModelForm):
class Meta:
model = pdftabel_tool_
fields = ['apn', 'owner_name']
apn = forms.ModelChoiceField(queryset= Field.objects.values_list('name', flat=True), empty_label="(Choose field)")
owner_name = forms.ModelChoiceField(queryset= Field.objects.values_list('name', flat=True), empty_label="(Choose field)")
But due to some reasons like 'self' is not available in form.py. I can only access it in views.py. So I want to make it like
class FieldForm(ModelForm):
class Meta:
model = pdftabel_tool_
fields = (
'apn',
'owner_name',)
How can I make these fields as dropdown like I did in my forms.py?
Why are you set on doing it in views.py? forms.py is the appropriate place to do this.
Instead of redefining your fields, you should use the form's __init__ method to override the querysets for your fields, like so:
class pdftabelModelForm(forms.ModelForm):
class Meta:
model = pdftabel_tool_
fields = ['apn', 'owner_name']
def __init__(self, *args, **kwargs):
super(pdftabelModelForm, self).__init__(*args, **kwargs)
self.fields['apn'].queryset = X
self.fields['owner_name'].queryset = X
EDIT: if you need to pass extra parameters to your form, update the init method to this:
def __init__(self, *args, **kwargs):
self.layer_id = self.kwargs.pop('layer_id')
super(pdftabelModelForm, self).__init__(*args, **kwargs)
self.fields['apn'].queryset = X
self.fields['owner_name'].queryset = X
And when you initialize your form from views.py, pass the parameter:
form = pdftableModelForm(layer_id=X)

django-crispy form - hide field label

I have a cripsy django form.
What is the best way to hide the field label in the template when I use {% cripsy form %}?
I do not want the user to see MY_FIELD_1 and MY_FIELD_2.
class mYForm(forms.ModelForm):
MY_FIELD_1 = forms.BooleanField()
MY_FIELD_2 = forms.BooleanField()
def __init__(self, *args, **kwargs):
...
...
self.helper = FormHelper()
self.helper.layout = Layout(
Field('MY_FIELD_1',),
Field('MY_FIELD_2',),
)
...
If you want to remove all labels from your form when using the crispy forms FormHelper then you can use:
self.helper.form_show_labels = False
If you want to remove labels from certain fields then you can do
self.fields['some_field'].label = False
Where some_field is the name of the field whose label you want to remove.

Initializing a MultipleChoiceField in Django CMS

I have a CharField (displayed_fields) in my model that I display in my form as a MultipleChoiceField. Currently, the form loads with nothing selected, even if the model's displayed_fields is non-empty.
I'd like the form to initialize to the previously selected items being selected. So far, I've tried addint different values of intial, including initial=ExamplePlugin.EMAIL_COLUMN and initial={'displayed_fields': ['name', 'office', 'phone']}, to forms.py's field declaration, which doesn't seem to change anything. Is it possible to initialize it like this, and if not, is there a better model to be using than CharField?
models.py:
class ExamplePlugin(CMSPlugin):
NAME_COLUMN = 'name'
OFFICE_COLUMN = 'office'
PHONE_COLUMN = 'phone'
EMAIL_COLUMN = 'email'
TITLE_COLUMN = 'title'
COLUMN_CHOICES = (
(NAME_COLUMN, 'First and Last Name'),
(OFFICE_COLUMN, 'Office Location'),
(PHONE_COLUMN, 'Phone Number'),
(EMAIL_COLUMN, 'Email Address'),
(TITLE_COLUMN, 'Title'),
)
displayed_fields = models.CharField(blank=False, verbose_name='Fields to show', max_length=255)
forms.py:
class ExampleForm(ModelForm):
def __init__(self, *args, **kwargs):
super(ExampleForm, self).__init__(*args, **kwargs)
displayed_fields = MultipleChoiceField(choices=ExamplePlugin.COLUMN_CHOICES, help_text="Select columns that you would like to appear.")
class Meta:
model = ExamplePlugin
I think you should do:
class ExampleForm(ModelForm):
displayed_fields = MultipleChoiceField(choices=ExamplePlugin.COLUMN_CHOICES, help_text="Select columns that you would like to appear.", initial=['name', 'office', 'phone'])
def __init__(self, *args, **kwargs):
super(ExampleForm, self).__init__(*args, **kwargs)
class Meta:
model = ExamplePlugin
MultipleChoiceField accepts a list as its default, I guess.

Why is "blank" is missing in django.forms.CharField, but present in django.db.models.CharField?

Background
I have a model with two fields that are set the blank:
class News(models.Model):
title = models.CharField(max_length = 50, blank = True)
info = models.TextField(blank = True)
The thing is that I want to set the max_length dynamically when the form is built, so I have a custom form:
class NewsForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(NewsForm, self).__init__(*args, **kwargs)
title_max_length = 20
info_max_length = 100
self.fields["title"] = forms.CharField(max_length = title_max_length)
self.fields["info"] = forms.CharField(
widget = forms.Textarea,
validators = [
MaxLengthValidator(info_max_length)
]
)
Note: Those two length values are actually fetched from the database, but I chose not to include that code to keep the examples shorter.
The problem
When I'm using those custom fields the blank option is overwritten/ignored.
I tried just adding the max_length, widget and validators to the existing fields, like this:
class NewsForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(NewsForm, self).__init__(*args, **kwargs)
title_max_length = 20
info_max_length = 100
self.fields["title"].max_length = title_max_length
self.fields["info"].widget = forms.Textarea
self.fields["info"].validators = [MaxLengthValidator(info_max_length)]
When doing this the blank option works, but the dynamic max_length is not applied to the form.
I tried to look in the django source, but I'm quite new so it's too much to take in right now.
Is there some way I can achieve this?
When creating your form, add the following parameter to CharField apart from the max_length, widget and validators:
forms.CharField(...,required = False)
In Django, blank=True in models correlates to required=False in forms.

Categories

Resources