djangoreact-nativerandomdjango-filterdjango-filters

How to filter with a non non-model field?


I have a model with one of its fields is a random generated string as the following

from django.utils.crypto import get_random_string
class Competition(models.Model):
    name = models.CharField(verbose_name="challenge name", max_length=256)
    start_date = models.DateTimeField(verbose_name="start date")
    end_date = models.DateTimeField(verbose_name="end date")
    code = get_random_string(length=6)
    owner = models.ForeignKey(User, related_name="owner", on_delete=models.CASCADE)
    def __str__(self):
        return self.name

I am trying to have an endpoint like thathttp://192.168.1.2:8000/competitions/?code=${some_string} to access from react frontend. so in order to do so I have some filters

from django_filters import rest_framework as filters

class CompetitionFilter(filters.FilterSet):
    class Meta:
        model = competition
        fields = {
            "name": ["exact", "icontains"],
            "code": ["exact"],
            "start_date": ["exact", "lte", "gte"],
            "end_date": ["exact", "lte", "gte"],
            "owner": ["exact"],
        }

but I have an error saying TypeError: 'Meta.fields' must not contain non-model field names: code So how can I achieve it?


Solution

  • You could make the code field a model field and generate the random code via its default property:

    from django.utils.crypto import get_random_string   
    
    def set_code():
        return get_random_string(length=6)
    
    class Competition(models.Model):
            ...
            #we use set_code as a callable as per the Field.default docs
            code = models.CharField(max_length=6, default=set_code)
            ....
    

    One caveat: Any existing records will all have the same code value after a migration, so you'd need to cycle through them and reset via set_code(). New records should be fine.