简体   繁体   中英

What is the best approach to keep many different django model type choices DRY?

I decoupled my system into many applications where each of those have many models from which many have

This is the structure.

ROOT

  • core (for keeping generic stuff)
  • decoupled app
  • decoupled app
  • decoupled app
  • ...
  • decoupled app

In those apps many times models have model type choices. For example I have many models like this Event and Resource model.

VIDEO = 1
AUDIO = 2
IMAGE = 3
ARTICLE = 4
BOOK = 5
DOCUMENT = 6

RESOURCE_CONTENT_CHOICES = (
    (VIDEO, _("video")),
    (AUDIO, _("audio")),
    (IMAGE, _("image")),
    (ARTICLE, _("article")),
    (BOOK, _("book")),
    (DOCUMENT, _("document")),
)
class Resource(models.Model):
    title = models.CharField(max_length=256)
    resource_content = models.IntegerField(choices=RESOURCE_CONTENT_CHOICES)
    url = models.URLField()

PAST = 1
PRESENT = 2
FUTURE = 3

EVENT_TYPE_CHOICES = (
    (PAST, _("past")),
    (PRESENT, _("present")),
    (FUTURE, _("future")),
)
class Event(models.Model):
    title = models.CharField(max_length=256)
    event_type = models.IntegerField(choices=EVENT_TYPE_CHOICES)

Moreover many times tuples like EVENT_TYPE_CHOICES are used in other models as well. And I have around 20 other models with event_type like type field.

I was thinking that I could create types.py file in core app and write one dict for all types in one place so I can easily use in views, other models etc. because apps are not going to be reused in other projects anyway. But I'm not sure if this is the best approach.

So what would be the best approach to make everything scalable and DRY?

It depends on your intended use of the code.

The goal in decoupling apps is to isolate functionality that is expected to be generally reusable across many Django projects. However, you mentioned that:

"...your apps are not going to be reused in other projects anyway"

If that is the case, especially if the apps aren't considered to be good candidates for reuse, then strictly decoupling the apps isn't necessary. Therefore, use a single Python file in the core of your app which contains the various choices lists used by multiple models.

Like this:

# choices.py
RESOURCE_CONTENT_CHOICES = (
    ...
)
EVENT_TYPE_CHOICES = (
    ...
)

And import where needed:

# models.py
from myproject.core.choices import EVENT_TYPE_CHOICES

class Event(models.Model):
    # Optional: See additional note below
    EVENT_TYPE_CHOICES = EVENT_TYPE_CHOICES
    ...
    event_type = models.IntegerField(choices=EVENT_TYPE_CHOICES)
    ...

Alternatively, if you discover some of your apps are indeed good candidates for reuse, then decoupling them is more important than DRY. In that scenario, you should maintain your choices inside that app, even if some choices are duplicated elsewhere in other apps.

Additional note: using either approach, it's often very useful to have a reference to the choices within the model class. See: https://docs.djangoproject.com/en/1.7/ref/models/fields/#choices

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM