brfox
brfox

Reputation: 343

Is it possible to specify a QuerySet model dynamically as a string?

I am trying to build a query in Django dynamically. I have a lot of models that I would like to build a query for, but I don't want to code the name of the model, I want to pass it as a string.

from django.db.models.query import QuerySet
a_works = QuerySet(model_A)
a_doesnt_work = QuerySet("model_A")  # I want this to work, too

a_works.filter(pk=23)   # no error
a_doesnt_work.filter(pk=23)   # error: AttributeError: 'str' object has no attribute '_meta'

# then I am dynamically filtering different fields, which works fine with a_works
kwargs = { "%s__%s" % (field, oper) : val }
results = a_works.filter( **kwargs )

Is there a way to make the dynamic model selection work?

Upvotes: 4

Views: 3499

Answers (2)

Keval
Keval

Reputation: 773

Refer this: https://stackoverflow.com/a/75168880/7212249

from django.apps import apps

def get_app_label_and_model_name(instance: object):
"""
    get_model(), which takes two pieces of information — an “app label” and “model name” — and returns the model
     which matches them.
@return: None / Model
"""
app_label = instance._meta.app_label
model_name = instance.__class__.__name__
model = apps.get_model(app_label, model_name)
return model

How to use?

model_name = get_app_label_and_model_name(pass_model_object_here)

and use this to get dynamic model name for queries

model_name = get_app_label_and_model_name(pass_model_object_here)
query_set = model_name.objects.filter() # or anything else

Upvotes: 0

Daniel Roseman
Daniel Roseman

Reputation: 599956

Don't try and build querysets via the QuerySet class itself. You should always go via a model's Manager.

You can get the model via the get_model function defined in django.db.models. It takes parameters of the app name and the model name.

from django.db.models import get_model
model = get_model('myapp', 'modelA')
model.objects.filter(**kwargs)

Upvotes: 20

Related Questions