Closed javiermatos closed 4 years ago
Hi @javiermatos , sorry for the late reply on this (still figuring out the new Github notifications....)
So basically this is working "as expected". The way that Django works for this stuff when building a model form is:
generate a set of fields for a model (using fields_for_model
). So here this would be a call like
opts = cls.Meta
default_fields = fields_for_models(models.Account, opts.fields, ..., opts.widgets, ....)
2 - set those up on the class (so at this point default_fields
will use the right widget, but it would not use the floppyforms.gis.PointField
but the default Django one)
3 - override these defaults with manually declared fields. for example you declared address_location
here, so that field overrides everything from fields_for_model
(including stuff built up on meta)
Now, if you want to use a custom widget, you have a couple options (haven't tested any of these but I believe variants of these ideas work)
widget
for a model field, you can declare a default form field (with a default widget)class CustomFormPointField(loppyforms.gis.PointField):
widget = CustomPointWidget
class CustomModelPointField(PointField): # this is a model field
field_class = CustomFormPointField
# use the above in your models, then form fields will automatically use the right kind of field
form_class
and widgets
separatelyclass PointWidget(floppyforms.gis.PointWidget, floppyforms.gis.BaseOsmWidget):
pass
class AccountForm(forms.ModelForm):
class Meta:
model = models.Account
fields = '__all__'
widgets = {
'description': AdminTextareaWidget(),
'services': FilteredSelectMultiple(verbose_name='services', is_stacked=False),
'address_location': PointWidget(), # widget declared here...
}
field_classes = {
'address_location': floppyforms.gis.PointField # custom form field declared here
}
PointFields
to do the right thing, you could edit the default widget
class in your settings.py
or something:class PointWidget(floppyforms.gis.PointWidget, floppyforms.gis.BaseOsmWidget):
pass
from django.db.contrib.gis.db.models.fields import PointField as DjangoPointField
DjangoPointField.widget = PointWidget
Hope this helps
Great! Thank you so much for the detailed explanation! I had it working using the recommended way so it is fine. Thank you! :)
Glad to hear that you were able to get things working 😄
Hi,
I use to set custom widgets in my ModelForm for the admin site using the following pattern:
But I cannot do the same thing with a PointWidget. It works when setting address_location (my model field) directly as an attribute, but it does not work when using the widgets dictionary. There in my code sample there are two comments to show the different widget usages.
Is this behaving as expected? Am I forced to just use the approach that works instead of any other valid approach for standard Django widgets?
Regards!