Re: Override the default form field for a model field

2016-04-02 Thread James Pic
On Sat, Apr 2, 2016 at 10:44 AM, Florian Apolloner
 wrote:
> Yeah, I am also mostly worried about this. formfield for me is a quick
> shortcut, if you want to customize it, do it at the form level imo.

Does this mean we can close #26369 ?

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CALC3Kadk0RGFPi%3DVqhdsTxsMP52mGheYie_DuG%3Dw4LkH34YOdg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Override the default form field for a model field

2016-04-02 Thread Florian Apolloner


On Thursday, March 17, 2016 at 2:17:40 PM UTC+1, Tim Graham wrote:
>
> It seems useful, but I'm not sure if it increases the coupling between 
> model and forms in an undesirable way?
>

Yeah, I am also mostly worried about this. formfield for me is a quick 
shortcut, if you want to customize it, do it at the form level imo.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/7b9fe33f-b2e4-424e-bedc-426c1519068f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Override the default form field for a model field

2016-03-20 Thread James Pic
Yes, overriding the model field to change the definition of
formfield() works. It is indeed possible to define two model field
classes which have different formfield() methods, for example:

ManyToManyCheckboxField()
ForeignKeyRadioField()

Should Django provide such fields ?

formfield_callback is documented here:

https://docs.djangoproject.com/ja/1.9/ref/forms/models/#modelform-factory

It is one of the many ways there are to create a model form which
provides a radio widget for a foreign key for example.

However, the modelform then has to be passed around / inherited from
everywhere then.

Issue #26369 is about overriding the default widget that is used by a
formfield. The user story is like: I change the default widget used
for a model field and this change is applied everywhere.

Does this help to see the difference between just overriding in a
subclass, and overriding the default used by ModelForm ?

[0] https://code.djangoproject.com/ticket/26369

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CALC3Kaf5%3D0qNNq%3DdXbJWVxYQOb42VjnwhJ5E5TWHJhLHBQBCww%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Override the default form field for a model field

2016-03-19 Thread Tim Graham
I'm not sure whether or not to accept a related proposal to add a 
"formfield_defaults" keyword to model fields [0]. e.g.

link = models.OneToOneField(
...
formfield_defaults={
'widget': forms.RadioSelect,
}
)


It seems useful, but I'm not sure if it increases the coupling between 
model and forms in an undesirable way?

[0] https://code.djangoproject.com/ticket/26369

On Wednesday, March 9, 2016 at 1:43:16 PM UTC-5, Johannes Hoppe wrote:
>
> I got that, but you can't just make it your default widget, it will always 
> require more information. And I don't really like "defaults", again pep20.
>
> I currently don't have any need for action, therefore I won't do anything. 
> If you want to make a draft on how to refactor it, I'm happy to review it.
>
>> On Mar 9 2016, at 6:49 pm, James Pic > 
>> wrote: 
>>
>> I just meant that currently, if a user wants to make Select2 the
>> default widget for a model field, it is necessary to subclass the
>> modelfield class and override the model field's formfield() method
>> just to change the default widget it uses, sorry if it wasn't clear !
>>
>> -- 
>> You received this message because you are subscribed to a topic in the 
>> Google Groups "Django developers (Contributions to Django itself)" group.
>> To unsubscribe from this topic, visit 
>> https://groups.google.com/d/topic/django-developers/zG-JvS_opi4/unsubscribe
>> .
>> To unsubscribe from this group and all its topics, send an email to 
>> django-develop...@googlegroups.com .
>> To post to this group, send email to django-d...@googlegroups.com 
>> .
>> Visit this group at https://groups.google.com/group/django-developers.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/django-developers/CALC3Kaet9-Fy7BF64Fgtjh3MBz9EA7DR67FUkzhdS2HGg4821g%40mail.gmail.com
>> .
>> For more options, visit https://groups.google.com/d/optout.
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/02213ab6-58fc-4abd-8f82-e147ff059d72%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Override the default form field for a model field

2016-03-19 Thread James Pic
If we prefer to remove form related stuff from models, then we should
be able to register new default model forms:

models.py:

class YourModel(models.Model):
your_field = models.BooleanField()

forms.py:

class YourModelDefaultForm(django.?.ModelFormConfiguration):
class Meta:
help_texts = dict(your_field='your help text')

# Set it as default
django.?.register(YourModel, YourModelDefaultForm)

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CALC3KaeL2VefbA_GfkhaYf8jWJvr%3DsRLLjyP4FcHL9_q_EwfxA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Override the default form field for a model field

2016-03-19 Thread James Pic
On Thu, Mar 17, 2016 at 2:17 PM, Tim Graham  wrote:
> It seems useful, but I'm not sure if it increases the coupling between model
> and forms in an undesirable way?

The coupling is already there because model fields sit right
in-between the db and form fields, so I don't know if it would
actually /increase/ the coupling.

Another way is to extract out all form related methods from model
fields (value_from_object(), save_form_data(), formfield()) into a new
class.

Then instead of this model:

dbfield -> model field <- formfield

You'd have:

form field
\
   modelformfield
  |
   model field
   /
dbfield

modelformfield would have the formfield(), value_from_object(), and
save_form_data().

Anyway, are you sure it's not another issue ? I mean, even if we
decide to move formfield(), shouldn't it have overridable defaults ?

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CALC3KaeDx%3DN0wb5t_LjxNPaSBZa_buZxS2RLCpgDN6yx87-JOw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Override the default form field for a model field

2016-03-18 Thread Tim Graham
What I meant about increasing coupling is this question: do we want to go 
down the road of defining more and more form related things in models? Yes, 
there are already a few options that are primarily for model forms (e.g. 
editable and blank), but is it okay to add more or should we try to avoid 
that?

For example, there was also a similar proposal to allow specifying the form 
field when instantiating a model field [0].

selected = models.BooleanField(
...,
field=forms.ChoiceField(empty_label=None, widget=forms.RadioSelect())
)


If we accept the formfield_defaults proposal, then I don't see a clear 
place to draw the line to reject this other proposal.

[0] https://code.djangoproject.com/ticket/22609

On Thursday, March 17, 2016 at 9:46:30 AM UTC-4, is_null wrote:
>
> On Thu, Mar 17, 2016 at 2:17 PM, Tim Graham  > wrote: 
> > It seems useful, but I'm not sure if it increases the coupling between 
> model 
> > and forms in an undesirable way? 
>
> The coupling is already there because model fields sit right 
> in-between the db and form fields, so I don't know if it would 
> actually /increase/ the coupling. 
>
> Another way is to extract out all form related methods from model 
> fields (value_from_object(), save_form_data(), formfield()) into a new 
> class. 
>
> Then instead of this model: 
>
> dbfield -> model field <- formfield 
>
> You'd have: 
>
> form field 
> \ 
>modelformfield 
>   | 
>model field 
>/ 
> dbfield 
>
> modelformfield would have the formfield(), value_from_object(), and 
> save_form_data(). 
>
> Anyway, are you sure it's not another issue ? I mean, even if we 
> decide to move formfield(), shouldn't it have overridable defaults ? 
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/774f2f61-c749-4f82-b1e0-7dcc615f32d6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Override the default form field for a model field

2016-03-18 Thread Collin Anderson
A few thoughts, just to see if we can solve the problem by documenting some
existing code:

Would making a subclass overriding formfield() work?

class RadioSelectBoolean(models.BooleanField):
def formfield(self, *args, **kwargs):
kwargs['widget'] = forms.RadioSelect
super(RadioSelectBoolean, self).formfield(*args, **kwargs)

Or would using fields_for_model help?
https://github.com/django/django/blob/master/django/forms/models.py#L111

On Thu, Mar 17, 2016 at 1:49 PM, James Pic  wrote:

> If we prefer to remove form related stuff from models, then we should
> be able to register new default model forms:
>
> models.py:
>
> class YourModel(models.Model):
> your_field = models.BooleanField()
>
> forms.py:
>
> class YourModelDefaultForm(django.?.ModelFormConfiguration):
> class Meta:
> help_texts = dict(your_field='your help text')
>
> # Set it as default
> django.?.register(YourModel, YourModelDefaultForm)
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers  (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at https://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/CALC3KaeL2VefbA_GfkhaYf8jWJvr%3DsRLLjyP4FcHL9_q_EwfxA%40mail.gmail.com
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAFO84S4R_oHPRot1uL6p2kCqTppQb4yL0-d0DPQtgyy7VbWnAQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Override the default form field for a model field

2016-03-09 Thread Johannes Hoppe
I got that, but you can't just make it your default widget, it will always
require more information. And I don't really like "defaults", again pep20.  

  

I currently don't have any need for action, therefore I won't do anything. If
you want to make a draft on how to refactor it, I'm happy to review it.

> On Mar 9 2016, at 6:49 pm, James Pic  wrote:  

>

> I just meant that currently, if a user wants to make Select2 the  
default widget for a model field, it is necessary to subclass the  
modelfield class and override the model field's formfield() method  
just to change the default widget it uses, sorry if it wasn't clear !

>

> \--  
You received this message because you are subscribed to a topic in the Google
Groups "Django developers (Contributions to Django itself)" group.  
To unsubscribe from this topic, visit https://groups.google.com/d/topic
/django-developers/zG-JvS_opi4/unsubscribe.  
To unsubscribe from this group and all its topics, send an email to django-
developers+unsubscr...@googlegroups.com.  
To post to this group, send email to django-developers@googlegroups.com.  
Visit this group at https://groups.google.com/group/django-developers.  
To view this discussion on the web visit https://groups.google.com/d/msgid
/django-developers/CALC3Kaet9-Fy7BF64Fgtjh3MBz9EA7DR67FUkzhdS2HGg4821g%40mail.
gmail.com.  
For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/diyl3ltvflu4omhaebrin5lf9-0%40mailer.nylas.com.
For more options, visit https://groups.google.com/d/optout.


Re: Override the default form field for a model field

2016-03-09 Thread James Pic
I just meant that currently, if a user wants to make Select2 the
default widget for a model field, it is necessary to subclass the
modelfield class and override the model field's formfield() method
just to change the default widget it uses, sorry if it wasn't clear !

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CALC3Kaet9-Fy7BF64Fgtjh3MBz9EA7DR67FUkzhdS2HGg4821g%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Override the default form field for a model field

2016-03-09 Thread Johannes Hoppe
  
Regarding django-select2:  
  
I don’t want to provide fields at this point. Django has the concept of
widgets, and that is all I need for select2.  
  
You could overwrite the widget for all forms with a template processor, but
why? You’d need to know which db columns you need too search to filter the
query set, but in some cases you use a full text index or even elastic search.  
  
Besides, django-select2 started with fields and we moved it to widgets, just
to reduce the code base and complexity. After all, you need to maintain all
that code.  
  
I wouldn’t introduce too much magic (pep20). We made the field definition in
ModelForms mandatory and a lot of other “assumptions” have been deleted in
recent releases.  
  

> On Mar 9 2016, at 3:26 pm, James Pic  wrote:  

>

> On Wed, Mar 9, 2016 at 3:09 PM, Johannes Hoppe
 wrote:  
> We'll you can change the `default` form Field using  
> `django.db.models.Field.formfield`.

>

> Do you mean that, for example, an app like django-select2 could  
provide the following model fields ?

>

> \- Select2WidgetForeignKey,  
\- Select2WidgetOneToOneField,  
\- Select2MultipleWidgetManyToManyField,  
\- HeavySelect2WidgetForeignKey,  
\- HeavySelect2WidgetOneToOneField,  
\- HeavySelect2MultipleWidgetManyToManyField

>

> Also, wouldn't that require overriding the complete model class to  
change the default widget for an external app ?

>

> Also, would it be possible to conditionally enable Select2 widgets  
depending whether select2 is in INSTALLED_APPS without changing the  
model class ?

>

> Or perhaps everybody would benefit from changing these hardcoded  
values into attributes ?

>

> > But that is actually the thing I don't like I think this needs to go:  
> https://github.com/django/django/blob/d5f89ff6e873dbb2890ed05ce2aeae62879
2c8f7/django/db/models/fields/__init__.py#L869-L905

>

> If that goes, so should save_form_data and value_from_object, that's  
the first option I was talking about. I think we can still do that  
later. Changing the hardcoded defaults into instance attributes would  
still be useful when we do that.

>

> >  
> But at the end, I don't have a particular pain with all that. You can
easily  
> write your own model form, that changes the behavior. If you feel like  
> changing it, go ahead, but I would welcome a removing the cross
dependency.

>

> There's got to be code that couples db fields and form fields, perhaps  
it would help to move it around, but we'll also have to change it.

>

> Again, I think both solutions are good here: we don't have to choose  
one or another. When have the opportunity to do one before the other,  
which benefits to django's stability because moving .formfield()  
outside the model field is going to cause a lot of BC breaks in apps  
and projects.

>

> Thanks for sharing a bit of your time !

>

> Best

>

> \--  
  
Customer is king - Le client est roi - El cliente es rey.

>

> \--  
You received this message because you are subscribed to a topic in the Google
Groups "Django developers (Contributions to Django itself)" group.  
To unsubscribe from this topic, visit https://groups.google.com/d/topic
/django-developers/zG-JvS_opi4/unsubscribe.  
To unsubscribe from this group and all its topics, send an email to django-
developers+unsubscr...@googlegroups.com.  
To post to this group, send email to django-developers@googlegroups.com.  
Visit this group at https://groups.google.com/group/django-developers.  
To view this discussion on the web visit https://groups.google.com/d/msgid
/django-developers/CALC3KadmQM6TmKsabD3yf5_r5cqa0JiEe%2BHZph8reTRe0iO%2BCg%40m
ail.gmail.com.  
For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/a2cempdctyubtm9n4v815dwh1-0%40mailer.nylas.com.
For more options, visit https://groups.google.com/d/optout.


Re: Override the default form field for a model field

2016-03-09 Thread James Pic
On Wed, Mar 9, 2016 at 3:09 PM, Johannes Hoppe  wrote:
> We'll you can change the `default` form Field using
> `django.db.models.Field.formfield`.

Do you mean that, for example, an app like django-select2 could
provide the following model fields ?

- Select2WidgetForeignKey,
- Select2WidgetOneToOneField,
- Select2MultipleWidgetManyToManyField,
- HeavySelect2WidgetForeignKey,
- HeavySelect2WidgetOneToOneField,
- HeavySelect2MultipleWidgetManyToManyField

Also, wouldn't that require overriding the complete model class to
change the default widget for an external app ?

Also, would it be possible to conditionally enable Select2 widgets
depending whether select2 is in INSTALLED_APPS without changing the
model class ?

Or perhaps everybody would benefit from changing these hardcoded
values into attributes ?

> But that is actually the thing I don't like I think this needs to go:
> https://github.com/django/django/blob/d5f89ff6e873dbb2890ed05ce2aeae628792c8f7/django/db/models/fields/__init__.py#L869-L905

If that goes, so should save_form_data and value_from_object, that's
the first option I was talking about. I think we can still do that
later. Changing the hardcoded defaults into instance attributes would
still be useful when we do that.

>
> But at the end, I don't have a particular pain with all that. You can easily
> write your own model form, that changes the behavior. If you feel like
> changing it, go ahead, but I would welcome a removing the cross dependency.

There's got to be code that couples db fields and form fields, perhaps
it would help to move it around, but we'll also have to change it.

Again, I think both solutions are good here: we don't have to choose
one or another. When have the opportunity to do one before the other,
which benefits to django's stability because moving .formfield()
outside the model field is going to cause a lot of BC breaks in apps
and projects.

Thanks for sharing a bit of your time !

Best

-- 
http://yourlabs.org
Customer is king - Le client est roi - El cliente es rey.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CALC3KadmQM6TmKsabD3yf5_r5cqa0JiEe%2BHZph8reTRe0iO%2BCg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Override the default form field for a model field

2016-03-09 Thread Johannes Hoppe
We'll you can change the `default` form Field using
`django.db.models.Field.formfield`.

But that is actually the thing I don't like I think this needs to go: https://
github.com/django/django/blob/d5f89ff6e873dbb2890ed05ce2aeae628792c8f7/django/
db/models/fields/__init__.py#L869-L905

  

But at the end, I don't have a particular pain with all that. You can easily
write your own model form, that changes the behavior. If you feel like
changing it, go ahead, but I would welcome a removing the cross dependency.

> On Mar 9 2016, at 2:34 pm, James Pic  wrote:  

>

> Hi !

>

> Currently, by default, django's ModelForm uses form fields which are  
known to be compatible for the modelfield.

>

> By "compatible", I mean that it works when the ModelForm calls:

>

> \- ModelField.value_from_object() to get the initial formfield value  
for the model's field, via model_to_dict:  
https://github.com/django/django/blob/d5f89ff6e873dbb2890ed05ce2aeae628792c8f7
/django/forms/models.py#L101-L107  
\- ModelField.save_form_data() to save the form field's value, via  
construct_instance and save_m2m:  
https://github.com/django/django/blob/d5f89ff6e873dbb2890ed05ce2aeae628792c8f7
/django/forms/models.py#L47-L63  
https://github.com/django/django/blob/d5f89ff6e873dbb2890ed05ce2aeae628792c8f7
/django/forms/models.py#L427-L446

>

> To get the form field that's compatible with both ModelField methods,  
it calls ModelField.formfield(), via fields_for_models, again in  
django.forms.models:  
https://github.com/django/django/blob/d5f89ff6e873dbb2890ed05ce2aeae628792c8f7
/django/forms/models.py#L178

>

> There's got to be somewhere to couple both the db field and the form  
fields, and that seems to be in model fields. Note that ModelForm is  
not in django.forms, but in django.forms.models. That module  
encapsulates all coupling between django.forms and django.db.models.  
Perhaps it would have been a bit more intuitive to have such a set of  
modules: django.db, django.forms, django.models, django.models_forms.  
That would be moving code around, but the code wouldn't change and the  
result would be the same - so I figured when I gave it a try ;)

>

> Anyway, I opened this topic because I thought it would be cool if we  
could change the **default** formfield that is generated by  
ModelForms. I know there are means to override the defaults, but that  
means a lot of boilerplate code to override the form class every where  
(views, admin, admin inlines ...). This feature is heavily used in DAL  
v2 but really has nothing to do in an autocomplete app. It would be  
nice if we could change the **default** formfields used by ModelForm,  
from it's current logic "known-to-be-compatible", to an enhanced logic  
"best for project". "Best for project" is defined by the  
INSTALLED_APPS and the configuration these apps have. It would be  
really cool to have these features in Django so that every app could  
benefit from it because it would make form configuration a lot more  
DRY. Currently in Django, even if a project defines its own ModelFormS  
with their overrides (for every model), or even a custom  
ModelFormMetaclass, users have to override everything in Django to use  
that. This proposal is about allowing to change defaults.

>

> I found two ways of achieving this, perhaps there are more:

>

> \- make ModelFormMetaclass more configurable (a PoC  
https://github.com/jpic/xmodelform/blob/7de16ca1826c1bee91d9a5b616b78d3dff357f
a4/xmodelform/forms.py#L118-L170  
), but it's a bit more "fuzzy" to know if a form field is "compatible"  
(as defined above) with the model field, unless we permit form fields  
to override value_from_object() and save_form_data() which are  
currently in model fields. Note that save_form_data() can be called  
before or after form.save(), depending on wether it is a (many to many  
field, virtual field) or not (  
https://github.com/django/django/blob/d5f89ff6e873dbb2890ed05ce2aeae628792c8f7
/django/forms/models.py#L438  
). Also, we'd need a setting to allow a project to change what is the  
default modelform class or metaclass it would use in django factories.

>

> \- add instance attributes for model fields to override the currently  
hard coded defaults in formfield().

>

> Unless we can get more of the community involved in this, is seems  
more sane to go for the second option. The risk of doing something  
wrong(tm) when changing hard coded defaults to attributes is None as  
far as I understand.

>

> Are there any better way to override **default** form fields generated  
for models at the project-level ?

>

> \--  
You received this message because you are subscribed to a topic in the Google
Groups "Django developers (Contributions to Django itself)" group.  
To unsubscribe from this topic, visit https://groups.google.com/d/topic
/django-developers/zG-JvS_opi4/unsubscribe.  
To unsubscribe from this group and all its topics, send an email to django-
developers

Re: Override the default form field for a model field

2016-03-09 Thread James Pic
Hi !

Currently, by default, django's ModelForm uses form fields which are
known to be compatible for the modelfield.

By "compatible", I mean that it works when the ModelForm calls:

- ModelField.value_from_object() to get the initial formfield value
for the model's field, via model_to_dict:
https://github.com/django/django/blob/d5f89ff6e873dbb2890ed05ce2aeae628792c8f7/django/forms/models.py#L101-L107
- ModelField.save_form_data() to save the form field's value, via
construct_instance and save_m2m:
https://github.com/django/django/blob/d5f89ff6e873dbb2890ed05ce2aeae628792c8f7/django/forms/models.py#L47-L63
https://github.com/django/django/blob/d5f89ff6e873dbb2890ed05ce2aeae628792c8f7/django/forms/models.py#L427-L446

To get the form field that's compatible with both ModelField methods,
it calls ModelField.formfield(), via fields_for_models, again in
django.forms.models:
https://github.com/django/django/blob/d5f89ff6e873dbb2890ed05ce2aeae628792c8f7/django/forms/models.py#L178

There's got to be somewhere to couple both the db field and the form
fields, and that seems to be in model fields. Note that ModelForm is
not in django.forms, but in django.forms.models. That module
encapsulates all coupling between django.forms and django.db.models.
Perhaps it would have been a bit more intuitive to have such a set of
modules: django.db, django.forms, django.models, django.models_forms.
That would be moving code around, but the code wouldn't change and the
result would be the same - so I figured when I gave it a try ;)

Anyway, I opened this topic because I thought it would be cool if we
could change the **default** formfield that is generated by
ModelForms. I know there are means to override the defaults, but that
means a lot of boilerplate code to override the form class every where
(views, admin, admin inlines ...). This feature is heavily used in DAL
v2 but really has nothing to do in an autocomplete app. It would be
nice if we could change the **default** formfields used by ModelForm,
from it's current logic "known-to-be-compatible", to an enhanced logic
"best for project". "Best for project" is defined by the
INSTALLED_APPS and the configuration these apps have. It would be
really cool to have these features in Django so that every app could
benefit from it because it would make form configuration a lot more
DRY. Currently in Django, even if a project defines its own ModelFormS
with their overrides (for every model), or even a custom
ModelFormMetaclass, users have to override everything in Django to use
that. This proposal is about allowing to change defaults.

I found two ways of achieving this, perhaps there are more:

- make ModelFormMetaclass more configurable (a PoC
https://github.com/jpic/xmodelform/blob/7de16ca1826c1bee91d9a5b616b78d3dff357fa4/xmodelform/forms.py#L118-L170
), but it's a bit more "fuzzy" to know if a form field is "compatible"
(as defined above) with the model field, unless we permit form fields
to override value_from_object() and save_form_data() which are
currently in model fields. Note that save_form_data() can be called
before or after form.save(), depending on wether it is a (many to many
field, virtual field) or not (
https://github.com/django/django/blob/d5f89ff6e873dbb2890ed05ce2aeae628792c8f7/django/forms/models.py#L438
). Also, we'd need a setting to allow a project to change what is the
default modelform class or metaclass it would use in django factories.

- add instance attributes for model fields to override the currently
hard coded defaults in formfield().

Unless we can get more of the community involved in this, is seems
more sane to go for the second option. The risk of doing something
wrong(tm) when changing hard coded defaults to attributes is None as
far as I understand.

Are there any better way to override **default** form fields generated
for models at the project-level ?

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CALC3Kae9vd2KY13nEaUjQV%3DYxP-aVNVY3DRBYPPgheF9u_81CQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Override the default form field for a model field

2016-03-09 Thread Johannes Hoppe
Hi Tim, and I guess that's you James?

Thanks for pointing me towards this discussion. Tho I do like the idea for 
the sake of `django-select2`, I think it's a bad idea for Django.
I don't think that `django.db` should be even aware of `django.forms`. I 
don't even like the current implementation that much. I don't think
that a db field needs to define it's form representation. It should be the 
other way around from my opinion. With single page apps and DRF on the rise,
forms are becoming less of a core feature than they used to.
With that perspective in mind, I think it's a bad idea to introduce even 
more cross dependencies.

@James: If this is only about widget definition in ModelForms, why not just 
use the Meta class?

Cheers,
Joe

On Monday, March 7, 2016 at 8:36:10 PM UTC+1, is_null wrote:
>
> Thanks Tim. Something like that would work, perhaps the first step 
> would be to make modelfield.formfield a bit more configurable ? 
>
> Currently, the default form field class for a model field is hardcoded 
> in the model field's formfield() method, ie: 
>
> https://github.com/django/django/blob/master/django/db/models/fields/related.py#L945
>  
>
> Changing this to an attribute allows to replace it in an 
> AppConfig.ready() method as such: 
>
> class TestApp(AppConfig): 
> name = 'select2_one_to_one' 
>
> def ready(self): 
> model = self.get_model('TestModel') 
> # Perhaps that's the kind of nice place to override this 
> kind of things 
> model._meta.get_field('test').formfield_defaults['widget'] 
> = forms.RadioSelect 
> # django-autocomplete-light users would execute something 
> like: 
> model._meta.get_field('test').formfield_defaults['widget'] 
> = autocomplete.Select2(url='my_autocomplete_url') 
>
> This also allows to change it when defining the field: 
>
> class TestModel(models.Model): 
> name = models.CharField(max_length=200) 
>
> test = models.OneToOneField( 
> 'self', 
> null=True, 
> blank=True, 
> related_name='related_test_models', 
> # This seems like it would always be useful 
> formfield_defaults={ 
> 'widget': forms.RadioSelect 
> } 
> ) 
>
> I checked that this changed rendering in the admin, and it felt pretty 
> awesome I recon, to see my override in the default form and inline 
> model forms too. 
>
> Here's what the poc patch looks like for ForeignKey (3 additions and 1 
> deletion, works on OneToOne field too): 
>
>
> https://github.com/jpic/django/commit/d102f362f3c1ceaf2d5224d71f788c0821a481ae
>  
>
> Of course, that works when the model field already supports a form 
> field. It doesn't solve the problem with virtual fields that don't 
> have a formfield() method like GenericForeignKey, where an app would 
> like to be able to provide a formfield() as well as logic for 
> modelfield.{value_from_object,save_form_data}(). Perhaps that's 
> something we could deal with later *if* we decide to deal with it ? 
>
> Meanwhile, could we perhaps start working on a consistent way to 
> configure formfield() in Django ? That doesn't solve all the use cases 
> I mentioned, but perhaps it would be a nice step forward. 
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/4762ff24-8f4e-4a9d-9ea4-160764b8622a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Override the default form field for a model field

2016-03-07 Thread James Pic
Thanks Tim. Something like that would work, perhaps the first step
would be to make modelfield.formfield a bit more configurable ?

Currently, the default form field class for a model field is hardcoded
in the model field's formfield() method, ie:
https://github.com/django/django/blob/master/django/db/models/fields/related.py#L945

Changing this to an attribute allows to replace it in an
AppConfig.ready() method as such:

class TestApp(AppConfig):
name = 'select2_one_to_one'

def ready(self):
model = self.get_model('TestModel')
# Perhaps that's the kind of nice place to override this
kind of things
model._meta.get_field('test').formfield_defaults['widget']
= forms.RadioSelect
# django-autocomplete-light users would execute something like:
model._meta.get_field('test').formfield_defaults['widget']
= autocomplete.Select2(url='my_autocomplete_url')

This also allows to change it when defining the field:

class TestModel(models.Model):
name = models.CharField(max_length=200)

test = models.OneToOneField(
'self',
null=True,
blank=True,
related_name='related_test_models',
# This seems like it would always be useful
formfield_defaults={
'widget': forms.RadioSelect
}
)

I checked that this changed rendering in the admin, and it felt pretty
awesome I recon, to see my override in the default form and inline
model forms too.

Here's what the poc patch looks like for ForeignKey (3 additions and 1
deletion, works on OneToOne field too):

https://github.com/jpic/django/commit/d102f362f3c1ceaf2d5224d71f788c0821a481ae

Of course, that works when the model field already supports a form
field. It doesn't solve the problem with virtual fields that don't
have a formfield() method like GenericForeignKey, where an app would
like to be able to provide a formfield() as well as logic for
modelfield.{value_from_object,save_form_data}(). Perhaps that's
something we could deal with later *if* we decide to deal with it ?

Meanwhile, could we perhaps start working on a consistent way to
configure formfield() in Django ? That doesn't solve all the use cases
I mentioned, but perhaps it would be a nice step forward.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CALC3KaeBNZwpwrY0QRisKNGdD98_0iJV2%3DNrH5Nzkd-892Xakw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Override the default form field for a model field

2016-03-07 Thread Tim Graham
One idea (and it could be a terrible one) after a few minutes of thinking 
about it is an API similar to the query lookup/tranform API where you could 
write something like:

from django.db import models
models.CharField.register_formfield(MyCustomFormField)

which would make all subsequent CharFields use that form field. I guess you 
could already monkeypatch models.Field.formfield to achieve a solution like 
that, but it requires copying/pasting the existing methods just to replace 
the hardcoded form classes.

I'm not sure how my idea could work in the case of model fields like 
BooleanField which have the possibility of more than one form field.

On Tuesday, March 1, 2016 at 1:57:16 PM UTC-5, is_null wrote:
>
> Hi all, 
>
> Currently, the model field defines the default form field that's used 
> by the modelform metaclass. It would be nice if an external app could 
> overwrite this. 
>
> For example, a user installs an app which provides a more elaborated 
> relation select field. They configure the app to be able provide a 
> better form field or widget to select a particular model. 
>
> Now, it's a bit boilerplate to override the default generated form 
> field for a relation to that model in every modelform, as such: 
>
> class FirstForm(forms.ModelForm): 
> group = BetterField(your_options) 
>
> class SecondForm(forms.ModelForm): 
> main_group = BetterField(your_options) 
>
> # and so on 
>
> Currently, forms.ModelForm will use a form field that's known to work 
> by default. It does so by delegating that logic to the model field 
> methods such formfield() & friends. 
>
> Perhaps it would be an improvement if forms.ModelForm would be able to 
> use a form field that's *best* by default. "Best" here, is defined by 
> the project: what optional apps are installed and what configuration 
> they have. 
>
> For example, some apps will focus on providing a specific business 
> logic field, virtual or not (ie. generic many to many, array field, 
> tagfield ...), and other apps would focus on specific UX 
> (autocompletion, popup selection like raw_id_fields, other kind of 
> AJAX widgets). Gluing these apps in a projects is always the same, 
> from a project to another. If this kind of glue could be encapsulated 
> in another app, and made available in forms.ModelForm to improve 
> defaults, then users would have more time to work on what makes their 
> project different, rather than the same boilerplate code over and over 
> again. 
>
> I've been experimenting with ways to mitigate this issue for a few 
> years now, and here's what I came up with: 
>
> - allow a form field to override the model field's default saving 
> logic, as the input format may change it: 
> ModelField.value_from_object(), ModelField.save_form_data() and 
> ModelField.save_relation_data() should be overidable by the form 
> field, 
> - allow an app to register "form field factory callbacks" to 
> ModelFormMetaclass 
>
> I've implemented all that in a separate app and experimented with it 
> for a while, and TBH it works and it's okay to have this in an 
> external app rather than in Django itself (PoC: 
> https://github.com/jpic/xmodelform ), even thought it implies that the 
> user has to override everything to use this ModelForm by default 
> (admin, views, forms ...), this is not known to have killed any kitten 
> so far. Unless some point out that it would be good to have it in 
> Django, I'd work on it in a separate app  
>
> BUT, before I go all-in with this and make users use it by providing 
> it as the "official way", there's still one thing that fails to 
> convince me that it's the way to go. Something that may seem 
> completely unrelated, because it's a completely different way to go, 
> but solves the same issue: shouldn't effort be put in making a proper 
> way to change model fields from an external app ? 
>
> Related research on this has been started already apparently, with 
> django-swappable-models. It seems like work has been started to enable 
> model class override. While that's obviously overkill in the case I'm 
> talking about here, I'm wondering: would it be better to research a 
> way to enable external model field override, rather than the 
> form-oriented design exposed above (xmodelform) ? 
>
> I wish this could be avoided, but I recon that when you've tried 
> django-autocomplete-light v2's ModelForm, it's like eating the 
> defended fruit. Most of our userbase consider that v3 is not complete 
> and won't upgrade from v2 until they have this feature. I can 
> understand them, having a ModelForm that generates form fields which 
> are beyond "known to work" and have it generate "best" form fields for 
> a project without any boilerplate code is damn beautiful to see. 
> That's why this issue has been so fascinating to me and at least those 
> from the user base who stood up for that. 
>
> So, all this considered, what do you prefer, 0. research on overriding 
> the model field, or 1. on 

Override the default form field for a model field

2016-03-01 Thread James Pic
Hi all,

Currently, the model field defines the default form field that's used
by the modelform metaclass. It would be nice if an external app could
overwrite this.

For example, a user installs an app which provides a more elaborated
relation select field. They configure the app to be able provide a
better form field or widget to select a particular model.

Now, it's a bit boilerplate to override the default generated form
field for a relation to that model in every modelform, as such:

class FirstForm(forms.ModelForm):
group = BetterField(your_options)

class SecondForm(forms.ModelForm):
main_group = BetterField(your_options)

# and so on

Currently, forms.ModelForm will use a form field that's known to work
by default. It does so by delegating that logic to the model field
methods such formfield() & friends.

Perhaps it would be an improvement if forms.ModelForm would be able to
use a form field that's *best* by default. "Best" here, is defined by
the project: what optional apps are installed and what configuration
they have.

For example, some apps will focus on providing a specific business
logic field, virtual or not (ie. generic many to many, array field,
tagfield ...), and other apps would focus on specific UX
(autocompletion, popup selection like raw_id_fields, other kind of
AJAX widgets). Gluing these apps in a projects is always the same,
from a project to another. If this kind of glue could be encapsulated
in another app, and made available in forms.ModelForm to improve
defaults, then users would have more time to work on what makes their
project different, rather than the same boilerplate code over and over
again.

I've been experimenting with ways to mitigate this issue for a few
years now, and here's what I came up with:

- allow a form field to override the model field's default saving
logic, as the input format may change it:
ModelField.value_from_object(), ModelField.save_form_data() and
ModelField.save_relation_data() should be overidable by the form
field,
- allow an app to register "form field factory callbacks" to ModelFormMetaclass

I've implemented all that in a separate app and experimented with it
for a while, and TBH it works and it's okay to have this in an
external app rather than in Django itself (PoC:
https://github.com/jpic/xmodelform ), even thought it implies that the
user has to override everything to use this ModelForm by default
(admin, views, forms ...), this is not known to have killed any kitten
so far. Unless some point out that it would be good to have it in
Django, I'd work on it in a separate app 

BUT, before I go all-in with this and make users use it by providing
it as the "official way", there's still one thing that fails to
convince me that it's the way to go. Something that may seem
completely unrelated, because it's a completely different way to go,
but solves the same issue: shouldn't effort be put in making a proper
way to change model fields from an external app ?

Related research on this has been started already apparently, with
django-swappable-models. It seems like work has been started to enable
model class override. While that's obviously overkill in the case I'm
talking about here, I'm wondering: would it be better to research a
way to enable external model field override, rather than the
form-oriented design exposed above (xmodelform) ?

I wish this could be avoided, but I recon that when you've tried
django-autocomplete-light v2's ModelForm, it's like eating the
defended fruit. Most of our userbase consider that v3 is not complete
and won't upgrade from v2 until they have this feature. I can
understand them, having a ModelForm that generates form fields which
are beyond "known to work" and have it generate "best" form fields for
a project without any boilerplate code is damn beautiful to see.
That's why this issue has been so fascinating to me and at least those
from the user base who stood up for that.

So, all this considered, what do you prefer, 0. research on overriding
the model field, or 1. on the model form ?

If 1., can we add the possibility to override the default ModelForm
class used by modelform_factory() and friends in Django ?

Thanks in advance for your guidance.

Best

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CALC3KaczUhnW4onQ%2B8qz3EZyHcD6%3Dxcap%2BPCuCxg6AvXCNRpCQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.