Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the advantages of using metaclasses in django-like form implementations?

First a little background ... I was going over the Django source code for forms to understand the implementation of forms in Django (and to learn some Python along the way). Django implements forms using a DeclaredMetaFields MetaClass.

Here is a very crude class diagram of a Django-like form implementation (link to sample code in gist).

Django-form-like implementation of ContactForm - Class Diagram

And here is an instance diagram.

Django-form-like implementation of ContactForm - Instance Diagram

Here is a very crude implementation the same class without resorting to meta-classes (link to sample code in gist).

A simple and crude implementation of ContactForm

I understand the metaclass concepts etc. and understand how the Django code works. Now for the questions.

  1. Other than the obvious benefits such as syntactical elegance etc. are there any other benefits for the meta-class implementation?
  2. Is the meta-class like implementation possible without resorting to an intermediate object like BoundField?
like image 722
Praveen Gollakota Avatar asked Mar 30 '11 00:03

Praveen Gollakota


People also ask

Why would you use metaclasses?

A metaclass is most commonly used as a class-factory. When you create an object by calling the class, Python creates a new class (when it executes the 'class' statement) by calling the metaclass.

What are metaclasses in Django?

Model Meta is basically the inner class of your model class. Model Meta is basically used to change the behavior of your model fields like changing order options,verbose_name, and a lot of other options. It's completely optional to add a Meta class to your model.

When should you use metaclasses Python?

Having considered the most common and concrete use cases, the only cases where you absolutely HAVE to use metaclasses are when you want to modify the class name or list of base classes, because once defined, these parameters are baked into the class, and no decorator or function can unbake them.

How does Django use metaclasses?

Instead, Django metaclasses provide a way to ensure that all developers — regardless of varying low-level technical expertise — start at the same baseline and can shift their focus to defining entities and modelling business logic and real-life relationships within their code.


1 Answers

Well syntactical benefits matters a lot. After all even classes in OOP languages is just a syntactical benefit of the language.

In your example of very crude implementation of meta-class-less form implementation you describe fields in Dict. Well you might have overlooked that it is actually SortedDict, because ordering of fields matters. So I'll need to define fields_order list as well.

Next big thing is ModelForm. Meta-class approach allows to simply say which Model do I use and which fields in Meta attribute and it automatically creates and maps fields to model. Without Metaclass approach I would probably have to use something like CreateFieldsFromModel and MapFieldsToModel. Or you might do that for me in __init__ method. But wait, __init__ method is already complex enough with lots of arguments like data, initial, files, and more.

class MyForm(Form):
    fields = {
        'one': ...
        ...
    }
    fields_order = [...]
    model_fields = ???

Class MyForm2(MyForm):
    fields = MyForm.fields + {...}

# ... hey this API sucks! I think I'll go with another framework.

And there are many more things which can be configured in forms and everything is documented.

So for me, because of huge configuration logic, it looks like Form just asks to be implemented through definition-object and factory-logic. And here comes python with its metaclasses to hide the factory from the user. And it is cool because it makes beginners to think less.

And well yea its syntactical sugar all around and its all about making easy to use API.

And yes it is possible not to use Metaclasses/BoundField or whatever else. In the end it is possible to write all implementation of forms in one function and have all definition in one big dict (or xml?) But will that be easy to use, easy to understand, easy to extend?

like image 84
Ski Avatar answered Oct 23 '22 10:10

Ski