Custom Django model field to store multiple values. Updated from original library to support Django 2.
Project description
A reusable Django model field to store collections.
This is a fork of a fork. The original repository does not appear to be active. I needed to use the library for Django 2.
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file django-2-collectionfield-0.0.4.tar.gz
.
File metadata
- Download URL: django-2-collectionfield-0.0.4.tar.gz
- Upload date:
- Size: 17.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/45.2.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.7.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9345527a7bf414431d80e06e4781bf879e36481c9ce3a312c43387b919cdd256 |
|
MD5 | bbbd82c555691d0428dd2d04e44b912f |
|
BLAKE2b-256 | 8337ac68d6501020e05dfcd7b3e34846f0fb829b82f599b4417fd19c3ba7ab42 |
File details
Details for the file django_2_collectionfield-0.0.4-py2.py3-none-any.whl
.
File metadata
- Download URL: django_2_collectionfield-0.0.4-py2.py3-none-any.whl
- Upload date:
- Size: 18.2 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/45.2.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.7.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1c255ee71dac55658a8cd024dcd552514d513d025782cc895647153cd22a28a6 |
|
MD5 | 4f75f46ef774ed4353a9e8748e63ca99 |
|
BLAKE2b-256 | b60f4da464bf935499ba6caf444a63b57ac87acd5cf757a8387af1869edaba62 |