Django cyclic imports and typechecking with mypy

974 views Asked by At

I'm trying to create a simple custom manager with one of my Django models. It causes a cyclic import since I'm trying to import the manager from models.py and the model from managers.py. However, because my manager is creating the model and adding some extra attributes, the type hint for the method is the model instance. I'm having trouble with fixing that type hint since it's not yet imported.

# models.py
from .managers import PublishedBundleManager

class PublishedBundle(models.Model):
    data = JSONField()
    md5_checksum = models.CharField(max_length=128)

    objects = PublishedBundleManager()

The manager has a method to help me create the model instance, but as a convenience, calculates a checksum to fill in during creation. To fix the cyclic imports, I made use of typing.TYPE_CHECKING

# managers.py
import typing as t

from django.apps import apps
from django.db import models

if t.TYPE_CHECKING:
    PublishedBundle = apps.get_model(app_label="the_hugh", model_name="PublishedBundle")

class PublishedBundleManager(models.Manager):  # Error 1
    def create_publish(self, data: t.Dict, description: str) -> PublishedBundle:  # Error 2
        PublishedBundle = apps.get_model(app_label="my_app", model_name="PublishedBundle")
        json_data = json.dumps(data, sort_keys=True)
        md5_checksum = hashlib.md5(json_data.encode("utf-8")).hexdigest()
        return PublishedBundle.objects.create(data=data, md5_checksum=md5_checksum)

However, I'm getting 2 errors.

  1. Missing type parameters for generic type "Manager" [type-arg]mypy(error)
  2. name 'PublishedBundle' is not defined

I'm fairly new with typed python and never faced this issue before. I understand that 2 is happening because PublishedBundle hasn't yet been defined, but I can't define it because it causes a cyclic import. Can anyone help me out please?

1

There are 1 answers

0
l0b0 On

One simple way to work around this is to have the manager and the model in the same file. They are intricately related anyway.