All Projects β†’ bashu β†’ django-cached-modelforms

bashu / django-cached-modelforms

Licence: BSD-2-Clause license
🌟 ModelChoiceField implementation that can accept lists of objects, not just querysets

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to django-cached-modelforms

infinispan-spring-boot
Infinispan Spring Boot starter. Use this starter in your Spring Boot applications to help you use Infinispan+Spring integration in embedded and client/server mode
Stars: ✭ 61 (+335.71%)
Mutual labels:  caching
bkt
bkt is a subprocess caching utility, available as a command line binary and a Rust library.
Stars: ✭ 117 (+735.71%)
Mutual labels:  caching
EFCache
Second Level Cache for Entity Framework 6.1
Stars: ✭ 97 (+592.86%)
Mutual labels:  caching
grav-plugin-advanced-pagecache
Grav AdvancedPageCache Plugin
Stars: ✭ 19 (+35.71%)
Mutual labels:  caching
kdk memcached object cache
Object cache driver for Memcached in WordPress (based on Memcached Redux)
Stars: ✭ 20 (+42.86%)
Mutual labels:  caching
wagtail-cache
A simple page cache for Wagtail based on the Django cache middleware.
Stars: ✭ 63 (+350%)
Mutual labels:  caching
PHP-File-Cache
Light, simple and standalone PHP in-file caching class
Stars: ✭ 34 (+142.86%)
Mutual labels:  caching
endorphin
Key-Value based in-memory cache library which supports Custom Expiration Policies
Stars: ✭ 14 (+0%)
Mutual labels:  caching
Foundatio.Samples
Foundatio Samples
Stars: ✭ 34 (+142.86%)
Mutual labels:  caching
DailyBugle
πŸ“°Modern MVVM Android application following single activity architecture which fetches news from πŸ•·οΈ news API. this repository contains some best practices ⚑ of android development
Stars: ✭ 17 (+21.43%)
Mutual labels:  caching
hoardr
⚠️ ARCHIVED ⚠️ manage cached files
Stars: ✭ 19 (+35.71%)
Mutual labels:  caching
webuntis
A API library that makes it easy to access the Webuntis JSON RPC 2.0 API
Stars: ✭ 22 (+57.14%)
Mutual labels:  caching
powered-cache
The most powerful caching and performance suite for WordPress.
Stars: ✭ 31 (+121.43%)
Mutual labels:  caching
sfsdb
Simple yet extensible database you already know how to use
Stars: ✭ 36 (+157.14%)
Mutual labels:  caching
stash
Key-value store abstraction with plain and cache driven semantics and a pluggable backend architecture.
Stars: ✭ 71 (+407.14%)
Mutual labels:  caching
loQL
loQL is a lightweight, open source npm package that caches API requests with service workers, unlocking performance gains and enabling offline use.
Stars: ✭ 49 (+250%)
Mutual labels:  caching
maki
[beta] persistent memoization of computations, e.g. for repeatable tests and benchmarks
Stars: ✭ 16 (+14.29%)
Mutual labels:  caching
java-core
Collections of solutions for micro-tasks created while building modules as part of project. Also has very fun stuffs :)
Stars: ✭ 35 (+150%)
Mutual labels:  caching
cachegrand
cachegrand is an open-source fast, scalable and secure Key-Value store, also fully compatible with Redis protocol, designed from the ground up to take advantage of modern hardware vertical scalability, able to provide better performance and a larger cache at lower cost, without losing focus on distributed systems.
Stars: ✭ 87 (+521.43%)
Mutual labels:  caching
trickster
Open Source HTTP Reverse Proxy Cache and Time Series Dashboard Accelerator
Stars: ✭ 1,753 (+12421.43%)
Mutual labels:  caching

django-cached-modelforms

The application provides ModelForm, ModelChoiceField, ModelMultipleChoiceField implementations that can accept lists of objects, not just querysets. This can prevent these fields from hitting DB every time they are created.

Authored by Vlad Starostin, and some great contributors.

The problem

Imagine the following form:

class MyForm(forms.Form):
    obj = ModelChoiceField(queryset=MyModel.objects.all())

Every time you render the form ModelChoiceField field will hit DB. What if you don't want it? Can't you just pass the list of objects (from cache) to the field? You can't. What to do? Use cached_modelforms.CachedModelChoiceField.

The solution

Form with cached_modelforms.CachedModelChoiceField:

# forms.py

from cached_modelforms import CachedModelChoiceField

class MyForm(forms.Form):
   obj = CachedModelChoiceField(objects=lambda:[obj1, obj2, obj3])

This field will act like regular ModelChoiceField, but you pass a callable that returns the list of objects, not queryset, to it. Calable is needed because we don't want to evaluate the list out only once.

A callable can return:

  • a list of objects: [obj1, obj2, obj3, ...]. obj should have pk property and be coercible to unicode.
  • a list of tuples: [(pk1, obj1), (pk2, obj2), (pk3, obj3), ...].
  • a dict: {pk1: obj1, pk2: obj2, pk3: obj3, ...}. Note that dict is unsorted so the items will be ordered by pk lexicographically.

Same is for cached_modelforms.CachedModelMultipleChoiceField.

Warnings

There is no special validation here. The field won't check that the object is an instance of a particular model, it won't even check that object is a model instance. And it's up to you to keep cache relevant. Usually it's not a problem.

Model Form

But what about model forms? They still use original ModelChoiceField for ForeignKey fields. This app has its own ModelForm class that uses cached_modelforms.CachedModelChoiceField and cached_modelforms.CachedModelMultipleChoiceField. The usage is following:

# models.py

class Category(models.Model):
    title = CharField(max_length=64)

class Tag(models.Model):
    title = CharField(max_length=64)

class Product(models.Model):
    title = CharField(max_length=64)
    category = models.ForeignKey(Category)
    tags = models.ManyToManyField(Tag)

# forms.py

import cached_modelforms

class ProductForm(cached_modelforms.ModelForm):
    class Meta:
        model = Product
        objects = {
            'category': lambda:[...], # your callable here
            'tags': lambda:[...], # and here
        }

That's all. If you don't specify objects for some field, regular Model[Multiple]ChoiceField will be used.

m2m_initials

If you use ManyToManyField in ModelForm and load an instance to it, it will make one extra DB request (JOINed!) – to get initials for this field. Can we cache it too? Yes. You need a function that accepts model instance and returns a list of pk's – initials for the field. Here's a modification of previous example:

# models.py

class Product(models.Model):
    title = CharField(max_length=64)
    category = models.ForeignKey(Category)
    tags = models.ManyToManyField(Tag)

    def tags_cached(self):
        cache_key = 'tags_for_%(product_pk)d' % {'product_pk': self.pk}
        cached = cache.get(cache_key)
        if cached is not None:
            return cached
        result = list(self.tags.all())
        cache.set(cache_key, result)
        return result

# forms.py

import cached_modelforms

class ProductForm(cached_modelforms.ModelForm):
    class Meta:
        model = Product
        objects = {
            'category': lambda:[...], # your callable here
            'tags': lambda:[...], # and here
        }
        m2m_initials = {'tags': lambda instance: [x.pk for x in instance.tags_cached()]}

Contributing

If you've found a bug, implemented a feature or customized the template and think it is useful then please consider contributing. Patches, pull requests or just suggestions are welcome!

License

django-cached-modelforms is released under the BSD license.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].