0

I want to create a custom field such that if the field is queried, then the filter is always __iexact.

Example:

class Domain(models.Model):
    domain = models.IExactCharField()
    name = models.CharField()

I want a query like Domain.objects.filter('domain=newdomain') to be rewritten as Domain.objects.filter('domain__iexact=newdomain').

I understand you can do this with a custom manager, but I want adding the field to add the custom manager. And if a custom manager is already defined, I want the managers functionality to be chained. Is this possible? I was looking at the contribute_to_class method and thought it might have some potential when defining the field.

John Smith
  • 179
  • 7

1 Answers1

0

The code below won't work - the lookup_type is being added elsewhere (in QuerySet) unfortunately. I'll take a look inside :)

class IExactCharField(models.CharField):
    def get_prep_lookup(self, lookup_type, value):
        return super(IExactCharField, self).get_prep_lookup('iexact', value)

It enforces iexact lookups - you can evantually add check of lookup_type before referencing to superclass.

PS. Bear in mind that some databases (SQLite) won't support case insensitive unicode string lookups.

EDIT: the only workaround I have is to make all domain fields lowercase on save() or some save signal.

pielgrzym
  • 1,647
  • 3
  • 19
  • 28
  • I noticed that too :) I'm working on a workaround that uses contribute_to_class a la http://stackoverflow.com/questions/609563/how-to-add-a-manager-from-field. will post shortly. thanks for your help! – John Smith Jun 07 '12 at 17:57
  • The question with custom manager is still how to detect inside get_query_set() in your custom manager that filter is looking up for field that should be iexact? – pielgrzym Jun 07 '12 at 18:05
  • basically, if the query is domain='', set it to domain__iexact=''. if the query is domain__exact='' raise an error. I do this by creating a custom manager. This adds a second problem: if a custom manager has already been defined, how do I account for that too. – John Smith Jun 07 '12 at 19:01
  • How do you check the query? As for the other manager - a funny solution comes in mind - a custom models.Model subclass (or mixin) that will automatically create a subclass of existing custom manager and replace existing custom manager with contribute_to_class with the new subclassed manager that does the magic and has a superclass that does it's own magic;)) – pielgrzym Jun 08 '12 at 11:22