+263773057669 info@clouditate.com

Python meta class and uses in Django meta class

A metaclass is a class whose instance is a class. It defines the behavior of classes and their instances, a class decorator. In the Django web framework, a metaclass is used to define an extra option for a model or form so that other classes within the web app know the capabilities of the model. The metaclass is referenced during the definition of the object instance before you define the class itself. This blog post will explain from class meta python

 Pythons support metaclasses in ways that other programming languages don’t. You can define custom metaclasses. In many cases, it isn’t much necessary to define these custom classes, but if you have used the Django web framework before, then you know metaclasses are important in models and forms.

If you work with python then you’ve used metaclasses without knowing it. Many Python programmers don’t stress about metaclasses in their code. However, you might find yourself having to use a metaclass.

Python meta class

What is a python metaclass

Metaclasses in python are a useful way to describe the behavior of a class. Metaprogramming is a programming technique used in a computer software component to have the ability to treat other components as described in their data. It means that a program can be designed to understand and even change other programs or modify it’s specification while executing. Python has a perfect syntax structure and modules that support meta class definition. Many people are better off not using metaclasses in python, but if you’re using the Django web framework, metaclasses are used in model and form definition. Read more on Django metaclasses.

A meta class in python can simply be defined as a class of class that describes the behavior of the class. A class is the instance of a meta class

Lisp programming language has a reputation for having a good meta programming facility and easy syntax. I advice you check basic Lisp meta programming.

Old style python class definition

Classes are not defined by inheriting from a base class. An instance of an old-style class is implemented from an instance. In old classes, obj.__class__ represent the class and type(obj) return the instance of the class. Here is an example:

#
#
# Old style class definition

class Hello:
   pass

obj = Hello()
obj.__class__

type(obj)

#
#
#

The old style python class definition was removed in python 3 >. Let’s look at the new style of defining classes.

New style python class definition

A class is created by inheriting from Object class. It is the only way to define a class since python 3. In the new style definition obj.__class__ is the same as type(obj). That’s the main difference between the two python class definition. Example code:

#
#
# New class definition example

class MyClass(Object):
   pass

obj = MyClass()
print(type(obj) is obj.__class__)

# end example
#
#

The above code will return true because obj.__class__ is same as type(obj).

Python classes and types

Everything in python is an object. So are classes. Let’s look at the type of class. The type of an object is a class, but the type of class is type.

Type is the metaclass and classes are the instances of the metaclass. This means that any python 3 class is an instance of the meta class.

Python classes have type as a metaclass. The metaclass is used to create classes which you’ll then use to create objects.

Creating python class dynamically

It’s possible to create python classes dynamically using the type facility. We use type and give it with three arguments, name of a class, a tuple of bases parent classes, dictionary with class attributes. Here is the example syntax:

#
#
#
Doy = type('Dog', (), {})
#
#
#

Creating custom python metaclass

Python allows a programmer to customize the class creation by passing the metaclass keyword in the class definition syntax. You can also do so by inheriting a class in which a metaclass was defined. Here is an example.

#
#
# Define Meta Class
class MyMetaClass(type):
    pass

# Define a class that takes the MyMetaClass 
class MyClass(metaclass=MyMetaClass):
    pass

# A class thatinherits a MyClass class
class MyChildclass(MyClass):
    pass

#
#
#

If you define a class and decide not to define a custom meta class, the default type is used.

__new__ and __init__ , python meta classes

You can define python metaclasses using __new__ and __init__ keywords. Let’s look at the example implimentation.

#
#
#

class MetaClass(type):
    def __new__(cls, name, bases, dict):
        pass

class AnotherMetaClass(type):
    def __init__(self, name, bases, dict):
        pass

#
#
#

__new__ is used if you want to define a dictionary (dict) or tuples before you create the class. __new__ is called after the object has been created to initialize it.

Singleton Class using a Metaclass

Singleton class is a class that can be instantiated by only one object. In python you can implement a singleton design using metaclasses. Example code.

#
#
#
class SingletonMetaClass(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(SingletonMeta,cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class MyClass(metaclass=SingletonMeta):
    pass
#
#
#

Example use of python metaclass

Python programmers can choose to use python metaclasses but the majority of people decide not to use it. However, there’re cases where your’re forced to use the metaclasses e.g. when dealing with django web framework.

Django web framework meta class

A model class is created by inheriting ModelBase class Model, the metaclass classes in the ModelBase are used to reflect database tables and we can simply use the simple syntax:

#
#
#

class User(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

#
#
#

For more information, read django meta class post, you’ll learn many meta class uses in django.

Django rest framework meta class

Django Rest Framework and its serializers use metaclasses. SerializerMetaclass creates a _declared_fields dictionary in the serializer class that contains all instances of the Field class that were included in the serializer class as attributes. Objects that implement SerializerMetaclass can then create a deep copy of these fields and implement them. Here is an example:

#
#
#

class ProfileSerializer(serializers.Serializer):
    email = serializers.EmailField()
    username = serializers.CharField(max_length=200)

#
#
#

Uses of Metaclasses in Python

  • proxies
  • Adding new methods
  • Property creation
  • Resource locking 
  • Profiling and logging

Defining a Metaclass in Python

A metaclass is defined as you define a normal class in Python but inheriting from type instead of object.

class HelloMeta(type):
    def __new__(cls, classname, superclasses, attributedict):
         print("class name: ", classname)
         print("super classes: ", superclasses)
         print("attribute: ", attributedict)

Let’s use the HelloMeta class example in the following example.

class A:
    pass
class Hello(A, metaclass=HelloMeta):
    pass
.................................
Result:
classname:  Hello
super classes:  (<class '__main__.A'>,)
attributedict:  {'__module__': '__main__', '__qualname__': 'Hello'}

We can go on and implement some useful and complicated metaclasses but this post is not about metaclasses in python but in the Django web framework.

Metaclasses in Django Models and Forms in Detail

In Django, we use a metaclass for defining extra attributes of either our model or form classes. The Meta API in Django helps other parts of the app to know the capabilities of each model.

What is class meta in Django

A metaclass in Django is a class attached to every model class of form class. It defines table name, verbose names, permissions, class nature (Whether abstract or not), default managers for the model, ordering when instances are called and many more other examples.

Metaclasses appear so much in the Django framework and you have to use them in your models and also your forms.

Simple Django Metaclass Example

A typical Django model class look like this:

class Student(models.Model):
     name = models.CharField(_('Student name'))
     .....................................
     class Meta:
         db_table = "dzd_students"
         verbose_name = _("Student")
         verbose_name_plural = _("Students")

We created a data model for Students and named it dzd_students [db_table], and the “Student” verbose name (human-readable name of the student instance)  using [verbose_name] and the plural for the verbose name. Our Meta class helped us name the instance object of the student class and also enabled us to name our database table for the model we just created.

Meta Options in Django

Let’s explore all the possible Django Metaclass fields you can use in your application.

abstract

Abstract option in Django models allows you to create a base model class with common fields and then let the other model classes inherit the abstract class.

If abstract is set to true then the class is an abstract class and can be inherited.

class ModelName(models.Model):
      ........................
      class Meta:
           abstact = true

Let’s explore an example of using an abstract class in Django. The following example contacts two classes the first one is the base model class which is going to be inherited by other models.

class BaseUser(models.Model):
      name = models.CharField()
      surname = models.CharField()
      dob = models.CharField()

      class Meta:
           abstact = true
class Teacher(BaseUser):
      grade = models.CharField()
      teaching_class = models.CharField()
      motto = models.CharFields()  
class Student(BaseUser):
      teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)

The Student and the Teacher model have the same “name, surname, dob” fields and so no reason to repeat them in each model. So the best solution is to define a base class with the common fields and let the Teacher and Student model inherit from it.

This is a comprehensive example of abstract classes in the Django framework. You can try new tricks and more fields in your base abstract class and child model classes.

db_table

The db_table meta field is used to name the database table created by the model. By default, Django automatically generates a table name using the model name and the application name that contains the model. Django joins the app label and the model’s class name.

The db_table meta option is then used to override the default Django app_label + model class name. Let’s see how the db_table meta option works with an example

class User(models.Model):
      name = models.CharField()
      surname = models.CharField()
      dob = models.CharField()

      class Meta:
           db_table = "bufjf_user"

With the db_table option, you can customize the database table names the way you want.

db_tablespace

A tablespace is a location where the actual data is stored. It offers an abstraction layer between the physical and logical layout of the database. In Django, you can define your own db_tablespace in the Django meta class option of every database model. Let’s explore one example:

class ExampleTableSpace:
    name = models.CharField(max_length=7)
    ....................................
    class Meta:
        db_tablespace = "mytables"

managed

If you set manage=True, the default setting, Django will manage your database table’s lifecycle. Django will create a database table with the migration command. If your model is backed by a database view, and you don’t want to issue a CREATE_TABLE instruction on migration, you can set the managed option to false. If you haven’t used the option, you can leave it as default.

×

Clouditate Services

×