Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does one use a custom widget with a generic UpdateView without having to redefine the entire form?

I have a model with a ManyToMany relation that I would like to update with a CheckBoxSelectMultiple widget while everything else uses the default generic form, but when I redefine that one form field, it is the only one that shows up in the UpdateView. Is there a way to use a widget with just one field without having to redefine the entire form?

Views.py:

from django.views.generic.edit import UpdateView

from kunden.models import Kunde, Unternehmenstyp
from kunden.forms import KundeEditForm

class KundeUpdate(UpdateView):
    model = Kunde
    form_class =  KundeEditForm
    template_name = 'kunden/kunde_update.html'
    success_url = '/'

forms.py:

from django.forms.widgets import CheckboxSelectMultiple
from django.forms import ModelMultipleChoiceField,ModelForm

from kunden.models import Kunde, Unternehmenstyp

class KundeEditForm(ModelForm):
    model = Kunde
    unternehmenstyp = ModelMultipleChoiceField(widget=CheckboxSelectMultiple,required=True, queryset=Unternehmenstyp.objects.all())

I know this has a painfully simple solution, so thanks for your patience in advance everyone.

While I'm at it can anyone recommend any django books worth reading? I've gone through the base tutorial, dug through documentation as needed, and read Two Scoops of Django: https://django.2scoops.org/ so if you can think of a book for someone at my level, that'd be greatly appreciated. thanks again

like image 652
skzryzg Avatar asked Jun 05 '13 10:06

skzryzg


2 Answers

Here's a mixin that allows you to define a widgets dictionary and still respects the fields list:

from django.forms.models import modelform_factory

class ModelFormWidgetMixin(object):
    def get_form_class(self):
        return modelform_factory(self.model, fields=self.fields, widgets=self.widgets)

It can be used with CreateView, UpdateView, etc. For example:

class KundleUpdate(ModelFormWidgetMixin, UpdateView):
    model = Kunde
    widgets = {
        'unternehmenstyp': CheckboxSelectMultiple,
    }
like image 100
Jonathan Potter Avatar answered Oct 22 '22 22:10

Jonathan Potter


Try this, with class Meta:

from django.forms.widgets import CheckboxSelectMultiple
from django.forms import ModelMultipleChoiceField,ModelForm

from kunden.models import Kunde, Unternehmenstyp

class KundeEditForm(ModelForm):
    class Meta: # model must be in the Meta class
        model = Kunde
    unternehmenstyp = ModelMultipleChoiceField(widget=CheckboxSelectMultiple,required=True, queryset=Unternehmenstyp.objects.all())

REF: https://docs.djangoproject.com/en/1.5/topics/forms/modelforms/#modelform

You can also use modelform factories if you only need to make a simple override:

from django.views.generic.edit import UpdateView
from django.forms.models import modelform_factory

from kunden.models import Kunde, Unternehmenstyp

class KundeUpdate(UpdateView):
    model = Kunde
    form_class =  modelform_factory(Kunde,
        widgets={"unternehmenstyp": CheckboxSelectMultiple })
    template_name = 'kunden/kunde_update.html'
    success_url = '/'

REF: https://docs.djangoproject.com/en/1.5/topics/forms/modelforms/#modelform-factory-function

like image 20
Thomas Avatar answered Oct 22 '22 23:10

Thomas