Search code examples
djangodjango-filterdjango-filters

django_filters picking up %(app_label)s_related_name as field name


(Django 1.8.14) So I have one model, which uses a ContentType to point to a collections of models across separate apps.

I want to be able to "plug in" the functionality linking that model to the other models in the separate app. So we have the follwing:

class MyModelMixin(models.Model):
    """ Mixin to get the TheModel data into a MyModel
    """
    updated_date = models.DateTimeField(null=True, blank=True)
    submission = GenericRelation(
        TheModel,
        related_query_name='%(app_label)s_the_related_name')
    class Meta:
        abstract = True

The main model model looks like this:

class TheModel(models.Model):
    """ This tracks a specific submission.
    """
    updated = models.DateTimeField()
    status = models.CharField(max_length=32, blank=True, null=True)
    final_score = models.DecimalField(
        decimal_places=2, max_digits=30, default=-1,
    )
    config = models.ForeignKey(Config, blank=True, null=True)
    content_type = models.ForeignKey(
        ContentType,
        blank=True,
        null=True)
    object_id = models.PositiveIntegerField(blank=True, null=True)
    my_model_instance = GenericForeignKey()

And the mixin is included in the MyModel models, which are available in many different apps.

When using a filter for this, using django filters, there is an issue. I have a filter that's supposed to be instantiated to each app when it's used. However when I instantiate, for example, with

class MyFilterSet(Filterset):
    def __init__(self, *args, **kwargs):
        self.config_pk = kwargs.pop('config_pk', None)
        if not self.config_pk:
            return
        self.config = models.Config.objects.get(pk=self.config_pk)
        self.custom_ordering["c_name"] =\
            "field_one__{}_the_related_name__name".format(
                     self.config.app_model.app_label,
                )
        super(MyFilterSet,self).__init__(*args, **kwargs)

However, when I use this, I get

FieldError: Cannot resolve keyword 'my_app_the_related_name field. Choices are: %(app_label)s_the_related_name, answers, config, config_id, content_type, content_type_id, final_score, form, form_id, id, object_id, section_scores, status, updated

How can %(app_label)s_the_related_name be in the set of fields, and how can I either make it render properly (like it does outside of django filters) or is there some other solution.


Solution

  • You have probably encountered issue #25354. Templating related_query_name on GenericRelation doesn't work properly on Django 1.9 or below.

    Added in Django 1.10 was related_query_name now supports app label and class interpolation using the '%(app_label)s' and '%(class)s' strings, after the fix was merged.