I know this has been addressed before but I am having trouble making an on change submit work. Here is my forms.py nothing special in the model or the view. I relize I only selected this for one field but if it worked I would apply it to the others?
#forms.py
from django import forms
from .models import rapidTill
class RapidTillForm(forms.ModelForm):
class Meta:
widgets = {'linkArms': forms.RadioSelect(attrs={'onchange': 'RapidTillForm.submit();'}), 'shank':forms.RadioSelect,
'caddy':forms.RadioSelect, 'liftAssist': forms.RadioSelect, 'folding': forms.RadioSelect}
fields = ['rows', 'space', 'folding', 'shank', 'caddy', 'linkArms', 'liftAssist','shank',]
model = rapidTill
and my form-template.html
{% for field in form %}
<span>{{field.errors}}</span>
<label>{{field.label_tag}}</label>
{{field}}</br>
{%endfor%}
the 'submint' does not require the Model name at the front
class RapidTillForm(forms.ModelForm):
class Meta:
widgets = {'linkArms': forms.RadioSelect(attrs={'onchange': 'submit();'}), 'shank':forms.RadioSelect,
'caddy':forms.RadioSelect, 'liftAssist': forms.RadioSelect, 'folding': forms.RadioSelect}
fields = ['rows', 'space', 'folding', 'shank', 'caddy', 'linkArms', 'liftAssist','shank',]
model = rapidTill
Related
I want to override the basic view in the Article snippet selector, which does not display the checkbox correctly.
class ArticleChooserMixin(ModelChooserMixin):
def get_edit_item_url(self, item):
# for Wagtail 4.x
return reverse(
"wagtailsnippets_app_name_article:edit", args=(quote(item.pk),)
)
class ArticleChooserViewSet(ModelChooserViewSet):
icon = "user"
model = Article
page_title = _("Choose a article")
per_page = 10
order_by = "title"
fields = ["title", "body", "url", "categories", "countries"]
chooser_mixin_class = ArticleChooserMixin
piece of code from the Article model
from dal import autocomplete
...
#register_snippet
class Article(
DraftStateMixin,
RevisionMixin,
index.Indexed,
ClusterableModel,
Orderable,
SourceDataMixin,
):
...
categories = ParentalManyToManyField("app_name.ArticleCategory", blank=True)
countries = ParentalManyToManyField("app_name.Country", blank=True)
...
FieldPanel("categories", widget=autocomplete.ModelSelect2Multiple())
FieldPanel("countries", widget=autocomplete.ModelSelect2Multiple()),
...
Similar problem: https://github.com/wagtail/wagtail-generic-chooser/issues/65
View from the snippet creation how I want it to look and form elements that display the currently selected item
current problem
As per the wagtail-generic-chooser docs - The creation form presented within the chooser is a plain Django ModelForm, which does not make use of the model's panel definition. If you pass a fields attribute on the ViewSet class, it will construct a ModelForm with all of those fields at their default settings. To override this, you can define your own ModelForm class and pass that as form_class:
from django import forms
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ["title", "body", "url", "categories", "countries"]
widgets = {
"categories": autocomplete.ModelSelect2Multiple(),
"countries": autocomplete.ModelSelect2Multiple(),
}
class ArticleChooserViewSet(ModelChooserViewSet):
# ...
form_class = ArticleForm
I have a model defined like below in models.py
class ImageGrab(models.Model):
title = models.CharField(max_length=50)
slug=models.CharField(max_length=200)
age=models.ForeignKey(Age, on_delete=models.CASCADE)
gender=models.ForeignKey(Gender, on_delete=models.CASCADE)
masked=models.ForeignKey(Mask, on_delete=models.CASCADE)
withBackpack=models.ForeignKey(Backpack, on_delete=models.CASCADE)
Filters for which are defined as below in filters.py:
class ImageFilterAge(django_filters.FilterSet):
class Meta:
model = ImageGrab
fields = ['age']
###others similar to this
class ImageFilter(django_filters.FilterSet):
class Meta:
model = ImageGrab
fields = ['age', 'gender', 'masked', 'withBackpack']
The view is like below defined in views.py
def images(request):
imagelist = ImageGrab.objects.all()
imagefilter = ImageFilter(request.GET, queryset=imagelist)
agefilter = ImageFilterAge(request.GET, queryset=imagelist)
genderfilter=ImageFilterGender(request.GET, queryset=imagelist)
maskedfilter= ImageFilterMask(request.GET, queryset=imagelist)
backpackfilter = ImageFilterBackpack(request.GET, queryset=imagelist)
return render(request, 'imglist.html', {'filter': imagefilter,'agefilter': agefilter.form, 'genderfilter':genderfilter.form, 'maskfilter':maskedfilter.form, 'backpackfilter':backpackfilter.form})
My template is like this, in imglist.html
<form method="get" name="search" id="search">
{{ agefilter }} <br>
{{ genderfilter }} <br>
{{ maskfilter }} <br>
{{ backpackfilter }} <br>
</form>
This is rendered by default as dropdown select form as given in image link below. I want to change this to say checkbox multiple select and/ or radio button for the filters.
Filtering Using Dropdown
How to go about doing this?
Thanks in advance.
I combined the two solutions given by both users above, and got the solution thus:
Filters.py:
age = ModelMultipleChoiceFilter(queryset=Age.objects.all(),widget=forms.CheckboxSelectMultiple())
Models.py
class Age(models.Model):
ageChoices=(
('Child', 'Child'),
('Adult', 'Adult'),
('Old', 'Old'),
)
age = models.CharField(max_length=5, choices=ageChoices)
What is good is that the filters seem to wok neatly on the data set as well.
Thanks to users Abdul Aziz Barkat & Vosem
Seeing how your models are set up you might want to create a django custom form on which you specify the fields and the input method for each field.
Although you also might want to rethink using Foreign Keys for something as simple as age, gender or withBackpack. You probably want to use other kinds of fields for those, like IntegerField or BooleanField
You can customize the filter generation by specifying filter_overrides in the filter sets Meta. So for your use you can do something like below to set CheckboxInput as the widget to be used:
from django import forms
from django.db import models
class ImageFilterAge(django_filters.FilterSet):
class Meta:
model = ImageGrab
fields = ['age']
filter_overrides = {
models.ForeignKey: {
'filter_class': django_filters.ModelChoiceFilter,
'extra': lambda f: {
'widget': forms.CheckboxInput,
},
},
}
You can also explicitly define the filter field to be able to specify it's widget:
from django import forms
class ImageFilterAge(django_filters.FilterSet):
age = django_filters.ModelChoiceFilter(queryset=Age.objects.all(), widget=forms.CheckboxInput)
class Meta:
model = ImageGrab
fields = ['age']
I am using radio buttons for user input in forms.py and want to save the rated value in django database.I have the following fields:
from product.models import Rating
from django.forms import forms
from django.forms.fields import ChoiceField
from django.forms import ModelForm
from django import forms
class RatingForm(forms.ModelForm):
class Meta:
model = Rating
fields = ('product', 'user', 'rating')
widgets = forms.ChoiceField(widget=forms.RadioInput(),
required=True)
Model.py
class Rating(models.Model):
CHOICES = (
('5-stars', '5-stars'),
('4-stars', '4-stars'),
('3-stars', '3-stars'),
('2-stars', '2-stars'),
('1-stars', '1-stars'),
)
product=models.ForeignKey(Product,null=True,blank=True, on_delete=models.PROTECT)
user=models.ForeignKey(User,null=True,blank=True, on_delete=models.PROTECT)
rating=models.ChoiceField(choices=CHOICES, max_length=128)
I didn't find any library for importing this widget. Below is the error i am facing:
AttributeError: module 'django.forms' has no attribute 'RadioInput'?
Please if any one can help? Or suggest any other way to do this?
The widget is called RadioSelect, not RadioWidget. See the documentation.
Note however, you must use the widget directly in the widgets attribute, not as part of a field; and widgets is a dictionary of field names to widgets:
widgets = {'rating': forms.RadioSelect}
I'd like to add some info to a model field to use at form rendering time. My real model has about 15 values of varying field types (adding and removing as I dev), and it does almost everything I need, so I'd rather not create custom model fields for all of them.
I'd like to do something like this:
from django.db import models
class MyModel(models.Model):
cost = models.DecimalField(max_digits=5,
decimal_places=2,
custom_info= {'glyph': 'glyphicon glyphicon-usd' }
)
And then in my form template use that glyph much like I'd use a verbose_name or help_text.
Something I learned from a post just the other day. Will defining the custom information on the form instead of the model work?
When you define formfield_callback on a forms.ModelForm it will iterate over the form fields and you can manipulate them. This comes in handy when you need to add a css class to widgets and don't want to explicitly override the field. Now you only need to put formfield_callback = modify_form_field on any forms.ModelForm where you want the custom_info to show up.
from django.db import models
def add_glyphicons(model_field):
form_field = model_field.formfield()
if isinstance(model_field, models.IntegerField):
form_field.custom_info = {'glyph': 'glyphicon glyphicon-usd'}
elif isinstance(model_field, models.CharField):
form_field.custom_info = {'glyph': 'glyphicon glyphicon-yen'}
return form_field
class MyModel(models.Model):
formfield_callback = add_glyphicons
class Meta:
model = MyModel
class MyOtherModel(models.Model):
formfield_callback = add_glyphicons
class Meta:
model = MyOtherModel
When I render my formset, one of the field renders as a select box because it is a foreign field in the model. Is there a way to change this to a text input? I want to populate that field by using Ajax auto complete. Adding a widget to the modelform is not working because the modelformset_factory takes a model and not a model form.
EDIT
My Model Form
class RecipeIngredientForm(ModelForm):
class Meta:
model = RecipeIngredient
widgets = { 'ingredient' : TextInput(), }
I use it in my view
RecipeIngredientFormSet = modelformset_factory(RecipeIngredient, form=RecipeIngredientForm)
objRecipeIngredients = RecipeIngredientFormSet()
EDITED MODEL FORM
class RecipeIngredientForm(ModelForm):
ingredient2 = TextInput()
class Meta:
model = RecipeIngredient
I create the form set like this
RecipeIngredientFormSet = modelformset_factory(RecipeIngredient, form=RecipeIngredientForm)
objRecipeIngredients = RecipeIngredientFormSet()
QUESTION
Do I have to use the formset in html? Can I just hard code the fields that get generated and using javascript I can create new fields and increment the "form-TOTAL-FORMS"? If I can then I do not have to worry about my model form.
Thanks
modelformset_factory does take a form. Here's the function signature from django.forms.models:
def modelformset_factory(
model, form=ModelForm, formfield_callback=lambda f: f.formfield(),
formset=BaseModelFormSet,
extra=1, can_delete=False, can_order=False,
max_num=0, fields=None, exclude=None):
If this isn't working for you, show some code and I'll try and see what is going wrong.
Edit after various comments As you point out, the widget argument is buggy when used in this way. So the solution is not to use it - it's a very recent addition in any case. Instead, define the field directly on the form:
class RecipeIngredientForm(forms.ModelForm):
ingredient = forms.ModelChoiceField(widget=forms.TextInput))
class Meta:
model = RecipeIngredient