Configuring field search functionality for custom fields in a Django model

I have a custom model field YearWithSurenessFieldthat is represented in python using a custom data type YearWithSureness. The constructor for YearWithSurenessis YearWithSureness(year='', is_certain=False), where yeareither '', or a four-digit year (as a string), but is_certainis a bool, representing whether I am really sure that the given year is correct. Fields like this type are stored in my database in the form year / is_certain, for example. "2008 / True", "2011 / False", "/ False", etc.

As an example, in the model Member, I have a field grad_year = YearWithSurenessField(...)in which the year of graduation is stored, and I am also sure if I know that the year I stored is correct.

What I would like to do is use something like

Member.objects.filter(grad_year__year=2011)

to get QuerySetall members whose grad_year is either "2011 / True" or "2011 / False". Similarly, I would like to use something like

Member.objects.filter(grad_year__range=(2000, 2011))

to get QuerySetall Members whose grad_year ranges from 2000 to 2011, regardless of whether it is grad_year.is_certainTrue or False.

Is it possible? I know that I can use Member.objects.filter (grad_year__contains = "2011") to get the first result, but I would like to use __year.

Here are the relevant classes cut off by extraneous code:

class YearWithSureness(object):
    def __init__(self, year='', is_certain=False):
        # ...

    def __str__(self):
        return "{year}/{is_certain}".format(year=self.year,
                                            is_certain=self.is_certain)

class YearWithSurenessField(models.Field):
    __metaclass__ = models.SubfieldBase

    def __init__(self, *args, **kwargs):
        # ...

    def to_python(self, value):
        # ...

    def get_prep_value(self, value):
        # ...

    def get_prep_lookup(self, lookup_type, value):
        if lookup_type in ('month', 'day'):
            raise TypeError('Lookup type {0} not supported.'.format(lookup_type))
        else:
            return super(YearWithSurenessField, self).get_prep_lookup(lookup_type, value)

    def value_to_string(self, obj):
        # ...
+3
source share
3 answers

, . , "" "is_certain" . , -, . -, , . , : , .

, . , , .

+3

-, : Django

- QuerySet, . ozan:

class PersonQuerySet(models.query.QuerySet):
    def in_age_range(self, min, max):
        return self.filter(age__gte=min, age__lt=max)

class PersonManager(models.Manager):
    def get_query_set(self):
         return PersonQuerySet(self.model)

    def __getattr__(self, name):
        return getattr(self.get_query_set(), name)

class Person(models.Model):
    age = #...
    objects = PersonManager()

. , :

Person.objects.in_age_range(20,30)
Person.objects.exclude(somefield = some_value).in_age_range(20, 30)
+3

Have you tried changing the behavior of get_prep_lookup to return only the year value when lookup_type == 'year'? You can return int (value.split ('/') [0])

I'm not sure that implementing such a custom field is the best option, is there really a good reason to avoid splitting values ​​into two separated fields?

0
source

All Articles