django-waffle icon indicating copy to clipboard operation
django-waffle copied to clipboard

Abstract base models

Open jsocol opened this issue 9 years ago • 6 comments

@foxannefoxanne emailed me a while ago—and true to form I've been terrible at getting back to email, so I'm moving this here—about the idea of implementing at least Flags, if not all 3 types, with abstract base models and concrete implementations, that would allow projects to extend the base models, specify a class for each type in settings, and write their own segmentation.

My gut tells me this is probably a good idea. For Flags, it'd look something like

class BaseFlag(models.Model):
    # all current flag model code
    class Meta(object):
        abstract = True

# models.py
class Flag(BaseFlag):
    pass

and a setting

WAFFLE_FLAG_CLASS = 'myproject.flags.MyFlag'

(or some kind of WAFFLE = {} settings dict #182, but you get the idea).

I think, think, this plays nicely with #144 (custom classes could override Flag.is_active) and #137 (they could also muck with cache however they needed to). But I'm putting this here to gather feedback, so if you have thoughts, pro or con, or concerns, anything, please share!

jsocol avatar Oct 21 '15 13:10 jsocol

Was looking for this exact thing today, trying to figure out an elegant way to segment based on my own models. Is there a semi-elegant approach you could suggest until this is (hopefully) implemented?

dmccaf avatar Jan 22 '16 17:01 dmccaf

I hacked together the ability to have flags based on arbitrary organizations. It feels ugly but it works. Looking forward to feedback.

Please see https://github.com/koliber/django-waffle/pull/1 for a working implementation.

The idea is that if you define a WAFFLE_ORG_MODEL in their settings file, the Flag model will have an additional field name organization. This field will be a ManyToMany to the model referenced in WAFFLE_ORG_MODEL. You also define a WAFFLE_USER_TO_ORG_FK_FIELD so that flag_is_active knows how to get the organization instance.

For example, if all my users belong to a company, I may have an acme.Company model. Each User has an FK named company to that model. I would add the following settings:

WAFFLE_ORG_MODEL = 'acme.Company'
WAFFLE_USER_TO_ORG_FK_FIELD = 'company'

People who don't define this get waffle functioning exactly as before. People who do define the above constants before creating and running new migrations get the org functionality as well.

koliber avatar Apr 20 '16 21:04 koliber

#108 also had the start of an implementation, but there was more work that would have to go into it.

jsocol avatar Apr 20 '16 21:04 jsocol

I would be interested in helping out with a more generalized solution. Do you think #108 is a start of an approach that would work? Do you have any concrete ways that you would like to see that implemented? I am asking as I just picked waffle up yesterday and would like to hear your input before starting off on another wild goose chase.

If I understand, the idea is that a user could create a drop-in replacement for the Flag model which inherits off of AbstractFlag. This would be done via a setting, akin to how Django custom user models are done.

What about the flag_is_active function? Would part of it be delegated to a method on the Flag model?

koliber avatar Apr 21 '16 06:04 koliber

I'd like to see the implementation as a drop-in model for Flag.

FlogFr avatar Jun 02 '16 11:06 FlogFr

WIP: https://github.com/PrimarySite/django-waffle/tree/feature/extensible-flags-COM-38

cleder avatar Jun 02 '16 13:06 cleder