Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ComputedFieldsModelMixin #82

Closed
stygmate opened this issue Oct 18, 2021 · 3 comments
Closed

ComputedFieldsModelMixin #82

stygmate opened this issue Oct 18, 2021 · 3 comments

Comments

@stygmate
Copy link

Using ComputedFields with other models class like SingletonModel of Django-Solo is impossible.
Adding the declaration of a ComputedFieldsModelMixin can resolve this issue, allowing us to write:

class MyBestModel(ComputedFieldsModelMixin, SingletonModel):
    pass
@jerch
Copy link
Collaborator

jerch commented Oct 18, 2021

Do you have a more detailed explanation, why it is impossible with ComputedFieldsModel and what a mixin could do about it? Note that there is a high chance, that computedfields will not work with arbitrary model overloads from custom django modules, as their functionality might collide with computedfields, esp. if the overloaded model class uses a highly customized save method or a special crafted meta class diverging from django's default too much.

For less intrusive 3rd party django modules, normally this should keep working:

class Model(ComputedFieldsModel, ThirdPartyModelClass):
    ...

(Note that the class inheritance order might be important, whether the cf logic should be applied before or after the 3rd party logic.)

@jerch
Copy link
Collaborator

jerch commented Dec 31, 2021

@stygmate Tested it with this dummy setup:

# models.py
from django.db import models
from solo.models import SingletonModel
from computedfields.models import ComputedFieldsModel, computed


class Solo(SingletonModel, ComputedFieldsModel):
    name = models.CharField(max_length=32)

    @computed(models.CharField(max_length=32), depends=[
      ('children', ['name'])
    ])
    def children_name_list(self):
        return ','.join(self.children.all().values_list('name', flat=True))


class Child(ComputedFieldsModel):
    name = models.CharField(max_length=32)
    solo = models.ForeignKey(Solo, related_name='children', on_delete=models.CASCADE)

    @computed(models.CharField(max_length=32, default=''), depends=[
      ('solo', ['name'])
    ])
    def solo_name(self):
        return self.solo.name

# admin.py
from django.contrib import admin
from solo.admin import SingletonModelAdmin

from .models import Solo, Child


class SoloAdmin(SingletonModelAdmin):
    readonly_fields = ('children_name_list',)
    list_display = ('children_name_list',)


class ChildAdmin(admin.ModelAdmin):
    readonly_fields = ('solo_name',)
    list_display = ('name', 'solo_name',)

admin.site.register(Solo, SoloAdmin)
admin.site.register(Child, ChildAdmin)

Works in both directions (Solo as concrete source for CF on Child, Solo with CF target). Why is it not working for you?

I see that SingletonModel has a cache option to lower db interactions. This ofc will not work with DCF out of the box, as DCF operates on the database. You would have to invalidate the cache entry somehow, which will be possible by a signal from DCF once #58 is done. For now the cache option on a model with (SingletonModel, ComputedFieldsModel) inheritance cannot be used, as you would miss the db value changes.

@jerch
Copy link
Collaborator

jerch commented Dec 31, 2021

@closing the issue, feel free to reopen if something is still unanswered.

@jerch jerch closed this as completed Dec 31, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants