Reputation: 413
I have a subclass of models.ForeignKey, the only purpose of which is to use a custom widget:
from django.db import models
from .models import Images
class GAEImageField(models.ForeignKey):
def __init__(self, **kwargs):
super(GAEImageField, self).__init__(Images, **kwargs)
def formfield(self, *args, **kwargs):
field = forms.ModelChoiceField(self, widget=ImageUploadWidget, *args, **kwargs)
field.queryset = Images.objects.all()
return field
The problem is, when I try to use this field, any parameters to __init__
are ignored. For instance, if I try this model:
class SomethingWithImage(models.Model):
name = models.CharField('Awesome name', max_length=64)
image = GAEImageField(verbose_name='Awesome image', blank=True)
...despite the fact I specified verbose_name, the label on a generated form will be "Image" and trying to specify empty value will raise an error even though I use blank=True
Upvotes: 0
Views: 158
Reputation: 4382
Well, the problem is with your formfield
method. If you look at the implementation used in the default ForeignKey
for example, you'll see it calls super
. I'd recommend something like this:
def formfield(self, **kwargs):
defaults = {
'widget': ImageUploadWidget,
}
defaults.update(kwargs)
return super(GAEImageField, self).formfield(**defaults)
The problem is, form fields don't extract any information from model fields. Form fields can be used completely independently from models, they don't have to be necessarily backed by a model field. That means all settings, like whether the field is required or not, its label etc. have to be passed as parameters to their constructors. It is the responsibility of the model field to create an appropriate instance of a form field, all settings included. The default implementation of django.db.models.fields.Field.formfield
takes care of that which is why you usually want to call the parent's method.
As for the blank
issue, try also setting null=True
, otherwise even though the form will accept a blank value, the database will reject it. Also, note that modifying the value of null
after syncdb
has been run requires a database migration.
Upvotes: 1