How can i use class attributes inside meta class in django

Question:

I have this code

class DistrictResource(ModelResource):
    model=models.District
    res_name="district"
    class Meta:
        queryset = self.model.District.objects.active()

how can i use self.model in meta as i get error if i use self

Asked By: Mirage

||

Answers:

You need to use

queryset = models.District.objects.active() 

instead of

queryset = self.model.District.objects.active()

in this case.

Edit:

You cannot access res_name inside the inner class because of the rule of scope resolution in Python:

A block is a piece of Python program text that is executed as a unit. The following are blocks: a module, a function body, and a class definition.

A scope defines the visibility of a name within a block.

The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods – this includes generator expressions since they are implemented using a function scope.

An easy rule to remember about Python Scope resolution is the LEGB rule:

L. Locals, i.e., names assigned within a function.

E. Enclosing function locals.

G. Globals

B. Built-ins.


class Meta is used by Django/Tastypie as configuration options when they use metaclass to construct the class. I am not sure why you would want to access a variable outside Meta from within Meta, rather than just define it inside Meta.

Answered By: K Z

For the ones still wanting to access a variable outside Meta from within Meta, one solution is to create the Meta class like this :

class DistrictResource(ModelResource):
    model=models.District
    res_name="district"
    Meta = type("Meta", (ModelBase,), {"foo": res_name, "queryset": model.objects.active()})

I’ve found this article giving knowledge about metaclasses : https://www.codingem.com/metaclasses-in-python/#Metaclasses_in_Python

Answered By: DeaX StormZ
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.