Once I populated my database with thousands and thousands of rows the widgets available for manipulating the data on the Admin site became virtually unusable.
So I have written a custom forms.Field that is a simple TextField that maps to a (hopefully) unique char field on a Model. The Field validates that the text maps to a single entry in the model, and provides a function that can be called from the Form that will reset the field's initial value to be the unique field (rather than the pk id). This has major speed and some usability advantages over the existing widgets/fields. It works pretty well, but I'm not so keen on the code and would appreciate advice for cleaning it up and making it easier to use. I especially don't like having to call fix_initial_form_value() from the form. Are there better ways to do this? Here is the custom Field code, followed by an example using it. # # A Field that acts as a TextField but must match an entry in the given # queryset/field. # class ModelChoiceTextField(forms.Field): def __init__(self, model, unique_field_name, attrs=None, *args, **kwargs): kwargs['widget'] = forms.widgets.TextInput(attrs) super(ModelChoiceTextField, self).__init__(*args, **kwargs) self.queryset = model.objects self.unique_field_name = unique_field_name def clean(self, value): if not value and not self.required: return None try: return self.queryset.get(**{self.unique_field_name: value}) except self.queryset.model.DoesNotExist: raise forms.ValidationError("Please enter a valid %s." % (self.queryset.model._meta.verbose_name,)) except self.queryset.model.MultipleObjectsReturned: raise forms.ValidationError("Please enter a unique %s." % (self.queryset.model._meta.verbose_name,)) # # Change the form's intial value for this field to it's chosen # member of the object. # # This assumes the field is for a Foriegn key and the initial value will # be a pk. # def fix_initial_form_value(self, form, field_name): if field_name in form.initial and form.initial[field_name]: obj = self.queryset.get(**{'pk': form.initial[field_name]}) form.initial[field_name] = getattr(obj, self.unique_field_name) Example usage: class PackageFileForm(forms.ModelForm): file = ModelChoiceTextField(OSFile, unique_field_name='file_name', attrs={'size':'60'}) def __init__(self, *args, **kwargs): super(ArgusPackageFileForm, self).__init__(*args, **kwargs) self.fields['file'].fix_initial_form_value(self, 'file') I'd also like for the field to set the 'required' flag automagically based on its field's 'blank' flag. But that may not be doable in the Field? Advice, comments and ideas welcome. Thanks, Chris Dodd --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~----------~----~----~----~------~----~------~--~---