Custom Django model field to store multiple values.
Project description
A reusable Django model field to store collections.
Features
- highly configurable model field (changing collection and item types, sorting, choices, item uniqueness and more)
- custom lookups to simplify queries over collection items
- form fields for working with collections
- collection item validators
- extended get_FIELD_display method for model fields with choices
- works with database backends without native support for multi-value columns (like ArrayField for PostgreSQL)
Installation
pip install django-collectionfield
Usage
Model field
Define model with field that stores lists of strings:
# models.py from django.db import models from collectionfield.models import CollectionField class MyModel(models.Model): tags = CollectionField()
Pass values to model field:
my_model = MyModel.objects.create(tags=['test', 'values']) my_model.values ['test', 'values']
Making queries
Retrieve model instances with particular value present in the collection:
MyModel.objects.filter(tags__has='test')
Retrieve model instances with ALL values present in the collection (ignoring items’ order):
MyModel.objects.filter(tags__hasall=['test', 'values'])
Retrieve model instances with ANY of values present in the collection:
MyModel.objects.filter(tags__hasany=['test', 'values'])
Customizing collections
Custom collection and item type:
class IntegerSet(models.Model): # This field will provide sets of integers # instead of default lists of strings: values = CollectionField(collection_type=set, item_type=int)
Sorting and uniqueness:
class SortedUniqueTextList(models.Model): # Before saving, items will be sorted and duplicates dropped: texts = CollectionField(sort=True, unique_items=True)
Choices and collection size limit:
class TaggedModel(models.Model): tags = CollectionField( # Both choices and max_items limit are checked during model validation. choices=( ('action', "Action"), ('comedy', "Comedy"), ('horror', "Horror"), # ... ), max_items=2 )
get_FIELD_display method can handle multiple choices and provide options to customize the display:
tagged_model = TaggedModel.objects.create(tags=['action', 'horror']) tagged_model.get_tags_display() "Action, Horror" def li_mapper(value, label): return "<li>{0}</li>".format(label) def ul_wrapper(field_display): return "<ul>{0}</ul>".format(field_display) tagged_model.get_tags_display(delimiter='', mapper=li_mapper, wrapper=ul_wrapper) '<ul><li>Action</li><li>Horror</li></ul>'
Django built-in validators work with entire field values. django-collectionfield provide validation of single collection items:
from collectionfield.validators import ( ItemMinValueValidator, ItemMaxValueValidator ) class IntegerList(models.Model): values = CollectionField( item_type=int, # item validators check each item separately: validators=[ItemMinValueValidator(1), ItemMaxValueValidator(5)] )
Form fields
django-collectionfield comes with 2 form fields:
from collectionfield.forms import CollectionField, CollectionChoiceField # ``collectionfield.forms.CollectionField`` converts comma-separated text # into collection of values: class MyForm(forms.Form): values = CollectionField() my_form = MyForm({'values': "A, B, C"}) my_form.is_valid() True my_form.cleaned_data['values'] ['A', 'B', 'C'] # ``collectionfield.forms.CollectionChoiceField`` behaves more like # regular MultipleChoiceField: class MyChoiceForm(forms.Form): values = CollectionChoiceField( choices=( ('action', "Action"), ('comedy', "Comedy"), ('horror', "Horror"), # ... ) ) my_choice_form = MyChoiceForm({'values': ['action', 'comedy']}) my_choice_form.is_valid() True my_choice_form.cleaned_data['values'] ['action', 'comedy']
Both form fields support the same set of parameters as the model field:
from collectionfield.forms import CollectionField class MyForm(forms.Form): values = CollectionField(collection_type=set, item_type=int) my_form = MyForm({'values': "1, 2, 1, 3"}) my_form.is_valid() True my_form.cleaned_data['values'] {1, 2, 3}
Representation in database
CollectionField converts its values into string of up to 1024 characters using the following format:
"|item1|item2|item3|"
Default delimiter (‘|’) and maximum length can be configured:
class MyModel(models.Model): values = CollectionField(delimiter="$", max_length=2000)
Requirements
Python: 2.7, 3.4, 3.5
Django: 1.8, 1.9, 1.10
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Filename, size | File type | Python version | Upload date | Hashes |
---|---|---|---|---|
Filename, size django_collectionfield-0.0.4-py2.py3-none-any.whl (20.0 kB) | File type Wheel | Python version py2.py3 | Upload date | Hashes View |
Filename, size django-collectionfield-0.0.4.tar.gz (15.7 kB) | File type Source | Python version None | Upload date | Hashes View |
Hashes for django_collectionfield-0.0.4-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 36de566775cb0b336251bec9d1396cf172916ba5a56e8ee471967201bd8ca56d |
|
MD5 | d150695ea6c43206cc302d3fa43f4677 |
|
BLAKE2-256 | aaed0e3d4ab0cf3b4997d380fbecc84fccbd07e46172b9b209a8afe4f3d7c18e |
Hashes for django-collectionfield-0.0.4.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | cd52aeee21736d36e52871e2efa4ca327469a6af29131865f2ef9840113646b1 |
|
MD5 | d3b4f6bfd671363ec85de4548bd83a54 |
|
BLAKE2-256 | ae658e3df52774bdac7ace13303301bedcd8480ca7080cb4f2f2f0116ee231ee |