4. Custom Encoder

A Custom Encoder in Flask is typically used to customize the way objects are serialized into JSON format. By default, Flask (through the jsonify function and the json module) can only handle certain types of objects. If you need to serialize custom objects (like classes or special data types), you need to extend the default JSON encoder.

Here’s a step-by-step explanation with an example:

Step-by-Step Explanation

  1. Default JSON Encoder:

    • The default encoder in Flask can handle basic Python data types like strings, lists, dictionaries, and numbers.

  2. Custom Objects:

    • When you have custom objects (like a class instance), you need a way to tell Flask how to convert these objects into JSON-compatible data types.

  3. Custom JSON Encoder:

    • You create a custom encoder by subclassing flask.json.JSONEncoder and overriding the default method. This method should return a serializable version of your custom object or call the superclass's default method if it can't handle the object.

  4. Using the Custom Encoder:

    • You tell Flask to use your custom encoder by setting it in the app configuration.

Example

Let's say you have a User class that you want to serialize to JSON.

from flask import Flask, jsonify
from flask.json import JSONEncoder
import datetime

app = Flask(__name__)

# Custom User class
class User:
    def __init__(self, id, username, email, created_at):
        self.id = id
        self.username = username
        self.email = email
        self.created_at = created_at

# Custom JSON Encoder
class CustomJSONEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, User):
            return {
                'id': obj.id,
                'username': obj.username,
                'email': obj.email,
                'created_at': obj.created_at.isoformat()
            }
        elif isinstance(obj, datetime.datetime):
            return obj.isoformat()
        return super().default(obj)

# Tell Flask to use the custom encoder
app.json_encoder = CustomJSONEncoder

@app.route('/user')
def get_user():
    user = User(1, 'johndoe', 'john@example.com', datetime.datetime.utcnow())
    return jsonify(user)

if __name__ == '__main__':
    app.run(debug=True)

Explanation of the Example

  1. User Class:

    • A simple class with id, username, email, and created_at attributes.

  2. CustomJSONEncoder:

    • Subclassed from JSONEncoder.

    • The default method checks if the object is an instance of User. If so, it returns a dictionary representing the User object.

    • It also checks for datetime objects to serialize them in ISO format.

    • Calls the superclass's default method for any other types it can't handle.

  3. Setting the Custom Encoder:

    • app.json_encoder = CustomJSONEncoder tells Flask to use CustomJSONEncoder instead of the default one.

  4. Endpoint:

    • The /user endpoint creates a User object and returns it using jsonify.

    • jsonify uses the custom encoder to convert the User object into JSON format.

Running the Example

When you run the Flask app and navigate to /user, you'll get a JSON response like this:

This response includes the serialized User object, demonstrating how the custom encoder converts the custom object to JSON.

Last updated