--- a/.settings/org.eclipse.core.resources.prefs Wed Jul 13 14:16:19 2011 +0200
+++ b/.settings/org.eclipse.core.resources.prefs Fri Jul 15 14:03:33 2011 +0200
@@ -1,4 +1,4 @@
-#Fri Jun 17 17:33:03 CEST 2011
+#Fri Jul 15 13:58:58 CEST 2011
eclipse.preferences.version=1
encoding//virtualenv/web/env/hdabo/lib/python2.6/site-packages/haystack/backends/__init__.py=utf-8
encoding//virtualenv/web/env/hdabo/lib/python2.6/site-packages/sortedm2m/fields.py=utf-8
@@ -6,7 +6,6 @@
encoding//virtualenv/web/env/hdabo/lib/python2.6/site-packages/sortedm2m/tests.py=utf-8
encoding//virtualenv/web/env/hdabo/lib/python2.6/site-packages/whoosh/analysis.py=utf8
encoding//virtualenv/web/env/hdabo/lib/python2.6/site-packages/wikitools/wiki.py=utf-8
-encoding//web/hdabo/fields.py=utf-8
encoding//web/hdabo/forms.py=utf-8
encoding//web/hdabo/management/commands/import_csv.py=utf-8
encoding//web/hdabo/management/commands/import_tag_popularity.py=utf-8
@@ -14,7 +13,6 @@
encoding//web/hdabo/models.py=utf-8
encoding//web/hdabo/search/french_whoosh_backend.py=utf-8
encoding//web/hdabo/tests/models.py=utf-8
-encoding//web/hdabo/tests/sortedm2mfield.py=utf-8
encoding//web/hdabo/utils.py=utf-8
encoding//web/hdabo/views.py=utf-8
encoding//web/hdabo/wp_utils.py=utf-8
--- a/web/hdabo/fields.py Wed Jul 13 14:16:19 2011 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,208 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.db import models, router
-from django.db.models import signals
-from django.db.models.fields.related import (create_many_related_manager,
- ManyToManyField, ReverseManyRelatedObjectsDescriptor)
-from hdabo.forms import SortedMultipleChoiceField
-from hdabo.utils import OrderedSet
-
-
-SORT_VALUE_FIELD_NAME = 'sort_value'
-
-
-def create_sorted_many_related_manager(superclass, rel):
- RelatedManager = create_many_related_manager(superclass, rel)
-
- class SortedRelatedManager(RelatedManager):
- def get_query_set(self):
- # We use ``extra`` method here because we have no other access to
- # the extra sorting field of the intermediary model. The fields
- # are hidden for joins because we set ``auto_created`` on the
- # intermediary's meta options.
- return super(SortedRelatedManager, self).\
- get_query_set().\
- order_by('%s.%s' % (
- rel.through._meta.db_table,
- rel.through._sort_field_name,))
-
- def _add_items(self, source_field_name, target_field_name, *objs):
- # join_table: name of the m2m link table
- # source_field_name: the PK fieldname in join_table for the source object
- # target_field_name: the PK fieldname in join_table for the target object
- # *objs - objects to add. Either object instances, or primary keys of object instances.
-
- # If there aren't any objects, there is nothing to do.
- from django.db.models import Model
- if objs:
- count = self.through._default_manager.count
- new_ids = OrderedSet()
- for obj in objs:
- if isinstance(obj, self.model):
- if not router.allow_relation(obj, self.instance):
- raise ValueError('Cannot add "%r": instance is on database "%s", value is on database "%s"' %
- (obj, self.instance._state.db, obj._state.db))
- new_ids.add(obj.pk)
- elif isinstance(obj, Model):
- raise TypeError("'%s' instance expected" % self.model._meta.object_name)
- else:
- new_ids.add(obj)
- db = router.db_for_write(self.through, instance=self.instance)
- vals = self.through._default_manager.using(db).values_list(target_field_name, flat=True)
- vals = vals.filter(**{
- source_field_name: self._pk_val,
- '%s__in' % target_field_name: new_ids,
- })
- new_ids = new_ids - OrderedSet(vals)
-
- if self.reverse or source_field_name == self.source_field_name:
- # Don't send the signal when we are inserting the
- # duplicate data row for symmetrical reverse entries.
- signals.m2m_changed.send(sender=rel.through, action='pre_add',
- instance=self.instance, reverse=self.reverse,
- model=self.model, pk_set=new_ids, using=db)
- # Add the ones that aren't there already
- count = self.through._default_manager.count
- for obj_id in new_ids:
- self.through._default_manager.using(db).create(**{
- '%s_id' % source_field_name: self._pk_val,
- '%s_id' % target_field_name: obj_id,
- self.through._sort_field_name: count(),
- })
- if self.reverse or source_field_name == self.source_field_name:
- # Don't send the signal when we are inserting the
- # duplicate data row for symmetrical reverse entries.
- signals.m2m_changed.send(sender=rel.through, action='post_add',
- instance=self.instance, reverse=self.reverse,
- model=self.model, pk_set=new_ids, using=db)
-
-
- return SortedRelatedManager
-
-
-class ReverseSortedManyRelatedObjectsDescriptor(ReverseManyRelatedObjectsDescriptor):
- def __get__(self, instance, instance_type=None):
- if instance is None:
- return self
-
- # Dynamically create a class that subclasses the related
- # model's default manager.
- rel_model = self.field.rel.to
- superclass = rel_model._default_manager.__class__
- RelatedManager = create_sorted_many_related_manager(superclass, self.field.rel)
-
- manager = RelatedManager(
- model=rel_model,
- core_filters={'%s__pk' % self.field.related_query_name(): instance._get_pk_val()},
- instance=instance,
- symmetrical=(self.field.rel.symmetrical and isinstance(instance, rel_model)),
- source_field_name=self.field.m2m_field_name(),
- target_field_name=self.field.m2m_reverse_field_name(),
- reverse=False
- )
-
- return manager
-
- def __set__(self, instance, value):
- if instance is None:
- raise AttributeError, "Manager must be accessed via instance"
-
- manager = self.__get__(instance)
- manager.clear()
- manager.add(*value)
-
-
-class SortedManyToManyField(ManyToManyField):
- '''
- Providing a many to many relation that remembers the order of related
- objects.
-
- Accept a boolean ``sorted`` attribute which specifies if relation is
- ordered or not. Default is set to ``True``. If ``sorted`` is set to
- ``False`` the field will behave exactly like django's ``ManyToManyField``.
- '''
- def __init__(self, to, sorted=True, **kwargs):
- self.sorted = sorted
- if self.sorted:
- # This is very hacky and should be removed if a better solution is
- # found.
- kwargs.setdefault('through', True)
- super(SortedManyToManyField, self).__init__(to, **kwargs)
- self.help_text = kwargs.get('help_text', None)
-
- def create_intermediary_model(self, cls, field_name):
- '''
- Create intermediary model that stores the relation's data.
- '''
- module = ''
-
- # make sure rel.to is a model class and not a string
- if isinstance(self.rel.to, basestring):
- bits = self.rel.to.split('.')
- if len(bits) == 1:
- bits = cls._meta.app_label.lower(), bits[0]
- self.rel.to = models.get_model(*bits)
-
- model_name = '%s_%s_%s' % (
- cls._meta.app_label,
- cls._meta.object_name,
- field_name)
- from_ = '%s.%s' % (
- cls._meta.app_label,
- cls._meta.object_name)
-
- def default_sort_value():
- model = models.get_model(cls._meta.app_label, model_name)
- return model._default_manager.count()
-
- # Using from and to model's name as field names for relations. This is
- # also django default behaviour for m2m intermediary tables.
- fields = {
- cls._meta.object_name.lower():
- models.ForeignKey(from_),
- # using to model's name as field name for the other relation
- self.rel.to._meta.object_name.lower():
- models.ForeignKey(self.rel.to),
- SORT_VALUE_FIELD_NAME:
- models.IntegerField(default=default_sort_value),
- }
-
- class Meta:
- db_table = '%s_%s_%s' % (
- cls._meta.app_label.lower(),
- cls._meta.object_name.lower(),
- field_name.lower())
- app_label = cls._meta.app_label
- ordering = (SORT_VALUE_FIELD_NAME,)
- auto_created = cls
-
- attrs = {
- '__module__': module,
- 'Meta': Meta,
- '_sort_field_name': SORT_VALUE_FIELD_NAME,
- '__unicode__': lambda s: 'pk=%d' % s.pk,
- }
-
- # Add in any fields that were provided
- if fields:
- attrs.update(fields)
-
- # Create the class, which automatically triggers ModelBase processing
- model = type(model_name, (models.Model,), attrs)
-
- return model
-
- def contribute_to_class(self, cls, name):
- if self.sorted:
- self.rel.through = self.create_intermediary_model(cls, name)
- super(SortedManyToManyField, self).contribute_to_class(cls, name)
- # overwrite default descriptor with reverse and sorted one
- setattr(cls, self.name, ReverseSortedManyRelatedObjectsDescriptor(self))
- else:
- super(SortedManyToManyField, self).contribute_to_class(cls, name)
-
- def formfield(self, **kwargs):
- defaults = {}
- if self.sorted:
- defaults['form_class'] = SortedMultipleChoiceField
- defaults.update(kwargs)
- return super(SortedManyToManyField, self).formfield(**defaults)
Binary file web/hdabo/fixtures/datasheet_10.yaml.bz2 has changed
Binary file web/hdabo/fixtures/datasheet_347.yaml.bz2 has changed
Binary file web/hdabo/fixtures/datasheet_all.yaml.bz2 has changed
--- a/web/hdabo/management/commands/import_csv.py Wed Jul 13 14:16:19 2011 +0200
+++ b/web/hdabo/management/commands/import_csv.py Fri Jul 15 14:03:33 2011 +0200
@@ -170,13 +170,13 @@
datasheet.save()
- datasheet.domains = domains
- datasheet.primary_periods = primary_periods
- datasheet.college_periods = college_periods
- datasheet.highschool_periods = highschool_periods
- datasheet.primary_themes = primary_themes
- datasheet.college_themes = college_themes
- datasheet.highschool_themes = highschool_themes
+ datasheet.set_domains(domains)
+ datasheet.set_primary_periods(primary_periods)
+ datasheet.set_college_periods(college_periods)
+ datasheet.set_highschool_periods(highschool_periods)
+ datasheet.set_primary_themes(primary_themes)
+ datasheet.set_college_themes(college_themes)
+ datasheet.set_highschool_themes(highschool_themes)
if row[u'Tag']:
--- a/web/hdabo/models.py Wed Jul 13 14:16:19 2011 +0200
+++ b/web/hdabo/models.py Fri Jul 15 14:03:33 2011 +0200
@@ -3,17 +3,26 @@
from django.conf import settings
from django.contrib.auth.models import User
from django.db import models
-from hdabo.fields import SortedManyToManyField
from hdabo.utils import Property, normalize
import datetime
+
+
+class SortedModelManager(models.Manager):
+ use_for_related_fields = True
+ def get_query_set(self):
+ qs = super(SortedModelManager, self).get_query_set()
+ if getattr(self, 'through', None) is not None and getattr(self.through, 'Meta', None) is not None and getattr(self.through.Meta, 'ordering', None) is not None:
+ qs = qs.order_by(*[self.through._meta.db_table + "." + f for f in self.through.Meta.ordering])
+ return qs
+
+
class Organisation(models.Model):
hda_id = models.CharField(max_length=512, unique=True, blank=False, null=False)
name = models.CharField(max_length=512, unique=False, blank=False, null=False)
location = models.CharField(max_length=512, unique=False, blank=True, null=True)
website = models.CharField(max_length=2048, unique=False, blank=True, null=True)
-
class Author(models.Model):
hda_id = models.CharField(max_length=512, unique=True, blank=False, null=False)
lastname = models.CharField(max_length=512, unique=False, blank=True, null=True)
@@ -33,13 +42,14 @@
label = models.CharField(max_length=512, unique=False, blank=False, null=False)
school_period = models.IntegerField(choices=TIME_PERIOD_CHOICES)
+ objects = SortedModelManager()
+
class Meta:
unique_together = ("label", "school_period")
def __unicode__(self):
return unicode(self.label)
-
class Domain(models.Model):
DOMAIN_PERIOD_CHOICES = (
(0, u'Global'),
@@ -56,6 +66,8 @@
label = models.CharField(max_length=512, unique=False, blank=False, null=False)
school_period = models.IntegerField(choices=DOMAIN_PERIOD_CHOICES)
+ objects = SortedModelManager()
+
class Meta:
unique_together = ("label", "school_period")
@@ -125,6 +137,38 @@
def __unicode__(self):
return unicode("%s : %s" % (self.name, self.insee))
+
+def generate_m2m_setter(m2m_field_name):
+
+ def set_m2m_field(self, list):
+
+ m2m_manager = getattr(self, m2m_field_name)
+ m2m_manager.clear()
+
+ through_klass = set_m2m_field.cache.get('through_klass', None)
+ if through_klass is None:
+ field = getattr(self.__class__, m2m_field_name)
+ through_klass = field.through
+ set_m2m_field.cache['through_klass'] = through_klass
+ for f in through_klass._meta.fields:
+ if isinstance(f, models.ForeignKey) and f.name != "datasheet":
+ set_m2m_field.cache['target_obj_field_name'] = f.name
+ break
+ target_obj_field_name = set_m2m_field.cache['target_obj_field_name']
+
+ for i, obj in enumerate(list):
+ kwargs = {
+ 'datasheet': self,
+ 'sort_value' : i,
+ target_obj_field_name: obj
+ }
+ new_rel = through_klass(**kwargs)
+ new_rel.save()
+ set_m2m_field.cache = {}
+
+ return set_m2m_field
+
+
class Datasheet(models.Model):
hda_id = models.CharField(max_length=512, unique=True, blank=False, null=False)
author = models.ForeignKey(Author, null=True, blank=True)
@@ -132,13 +176,13 @@
title = models.CharField(max_length=2048, unique=False, blank=False, null=False)
description = models.TextField(blank=True, null=True)
url = models.URLField(verify_exists=False, max_length=2048, blank=True, null=True)
- domains = SortedManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Global']}, related_name="datasheets")
- primary_periods = SortedManyToManyField(TimePeriod, limit_choices_to={'school_period':TimePeriod.TIME_PERIOD_DICT[u'Primaire']}, related_name="primary_periods_datasheets")
- college_periods = SortedManyToManyField(TimePeriod, limit_choices_to={'school_period':TimePeriod.TIME_PERIOD_DICT[u'Collège']}, related_name="college_periods_datasheets")
- highschool_periods = SortedManyToManyField(TimePeriod, limit_choices_to={'school_period':TimePeriod.TIME_PERIOD_DICT[u'Lycée']}, related_name="highschool_periods_datasheets")
- primary_themes = SortedManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Primaire']}, related_name="primary_themes_datasheets")
- college_themes = SortedManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Collège']}, related_name="college_themes_datasheets")
- highschool_themes = SortedManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Lycée']}, related_name="highschool_themes_datasheets")
+ domains = models.ManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Global']}, related_name="datasheets", through="Datasheet_domains")
+ primary_periods = models.ManyToManyField(TimePeriod, limit_choices_to={'school_period':TimePeriod.TIME_PERIOD_DICT[u'Primaire']}, related_name="primary_periods_datasheets", through="Datasheet_primary_periods")
+ college_periods = models.ManyToManyField(TimePeriod, limit_choices_to={'school_period':TimePeriod.TIME_PERIOD_DICT[u'Collège']}, related_name="college_periods_datasheets", through="Datasheet_college_periods")
+ highschool_periods = models.ManyToManyField(TimePeriod, limit_choices_to={'school_period':TimePeriod.TIME_PERIOD_DICT[u'Lycée']}, related_name="highschool_periods_datasheets", through="Datasheet_highschool_periods")
+ primary_themes = models.ManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Primaire']}, related_name="primary_themes_datasheets", through="Datasheet_primary_themes")
+ college_themes = models.ManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Collège']}, related_name="college_themes_datasheets", through="Datasheet_college_themes")
+ highschool_themes = models.ManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Lycée']}, related_name="highschool_themes_datasheets", through="Datasheet_highschool_themes")
town = models.ForeignKey(Location, null=True, blank=True)
format = models.ForeignKey(DocumentFormat, null=True, blank=True)
original_creation_date = models.DateField()
@@ -150,7 +194,7 @@
manual_order = models.BooleanField(default=False, db_index=True)
tags = models.ManyToManyField(Tag, through='TaggedSheet')
-
+
def validate(self, user):
self.validation_date = datetime.datetime.now()
self.validated = True
@@ -162,7 +206,10 @@
self.validated = False
self.validator = None
self.save()
-
+
+
+ set_domains = generate_m2m_setter("domains")
+
@Property
def domains_list(): #@NoSelf
def fget(self):
@@ -177,6 +224,9 @@
return locals()
+
+ set_primary_periods = generate_m2m_setter("primary_periods")
+
@Property
def primary_periods_list(): #@NoSelf
def fget(self):
@@ -192,6 +242,8 @@
return locals()
+ set_college_periods = generate_m2m_setter("college_periods")
+
@Property
def college_periods_list(): #@NoSelf
def fget(self):
@@ -206,6 +258,8 @@
return locals()
+ set_highschool_periods = generate_m2m_setter("highschool_periods")
+
@Property
def highschool_periods_list(): #@NoSelf
def fget(self):
@@ -220,6 +274,7 @@
return locals()
+ set_primary_themes = generate_m2m_setter("primary_themes")
@Property
def primary_themes_list(): #@NoSelf
@@ -236,6 +291,8 @@
return locals()
+ set_college_themes = generate_m2m_setter("college_themes")
+
@Property
def college_themes_list(): #@NoSelf
def fget(self):
@@ -250,6 +307,8 @@
return locals()
+ set_highschool_themes = generate_m2m_setter("highschool_themes")
+
@Property
def highschool_themes_list(): #@NoSelf
def fget(self):
@@ -299,5 +358,36 @@
return settings.WIKIPEDIA_VERSION_PERMALINK_TEMPLATE % (unicode(self.wikipedia_revision_id))
return locals()
+
+
+class SortedDatasheetLink(models.Model):
+ datasheet = models.ForeignKey(Datasheet, db_index=True, null=False, blank=False)
+ sort_value = models.IntegerField(null=False, blank=False)
+
+ class Meta:
+ abstract = True
+ ordering = ['sort_value']
+
+
+class Datasheet_domains(SortedDatasheetLink):
+ domain = models.ForeignKey(Domain, db_index=True, null=False, blank=False)
+
+class Datasheet_highschool_periods(SortedDatasheetLink):
+ timeperiod = models.ForeignKey(TimePeriod, db_index=True, null=False, blank=False)
+
+class Datasheet_highschool_themes(SortedDatasheetLink):
+ domain = models.ForeignKey(Domain, db_index=True, null=False, blank=False)
+
+class Datasheet_college_periods(SortedDatasheetLink):
+ timeperiod = models.ForeignKey(TimePeriod, db_index=True, null=False, blank=False)
+
+class Datasheet_college_themes(SortedDatasheetLink):
+ domain = models.ForeignKey(Domain, db_index=True, null=False, blank=False)
+
+class Datasheet_primary_periods(SortedDatasheetLink):
+ timeperiod = models.ForeignKey(TimePeriod, db_index=True, null=False, blank=False)
+
+class Datasheet_primary_themes(SortedDatasheetLink):
+ domain = models.ForeignKey(Domain, db_index=True, null=False, blank=False)
--- a/web/hdabo/tests/sortedm2mfield.py Wed Jul 13 14:16:19 2011 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-# -*- coding: utf-8 -*-
-from django import forms
-from django.db import models
-from django.test import TestCase
-from hdabo.fields import SortedManyToManyField
-from hdabo.forms import SortedMultipleChoiceField
-
-
-class Book(models.Model):
- name = models.CharField(max_length=50)
-
- def __unicode__(self):
- return self.name
-
-class Shelf(models.Model):
- books = SortedManyToManyField(Book, related_name='shelves')
-
-
-class Store(models.Model):
- books = SortedManyToManyField('sortedm2m.Book', related_name='stores')
-
-
-class MessyStore(models.Model):
- books = SortedManyToManyField('Book',
- sorted=False,
- related_name='messy_stores')
-
-
-class TestSortedManyToManyField(TestCase):
- model = Shelf
-
- def setUp(self):
- self.books = [Book.objects.create(name=c) for c in 'abcdefghik']
-
- def test_adding_items(self):
- shelf = self.model.objects.create()
- self.assertEqual(list(shelf.books.all()), [])
-
- shelf.books.add(self.books[2])
- self.assertEqual(list(shelf.books.all()), [self.books[2]])
-
- shelf.books.add(self.books[5], self.books[1])
- self.assertEqual(list(shelf.books.all()), [
- self.books[2],
- self.books[5],
- self.books[1]])
-
- # adding the same item again will append it another time
- shelf.books.add(self.books[2])
- self.assertEqual(list(shelf.books.all()), [
- self.books[2],
- self.books[5],
- self.books[1],
- self.books[2]])
-
- shelf.books.clear()
- self.assertEqual(list(shelf.books.all()), [])
-
- shelf.books.add(self.books[3], self.books[1], self.books[2])
- self.assertEqual(list(shelf.books.all()), [
- self.books[3],
- self.books[1],
- self.books[2]])
-
- def test_set_items(self):
- shelf = self.model.objects.create()
- self.assertEqual(list(shelf.books.all()), [])
-
- books = self.books[5:2:-1]
- shelf.books = books
- self.assertEqual(list(shelf.books.all()), books)
-
- books.reverse()
- shelf.books = books
- self.assertEqual(list(shelf.books.all()), books)
-
- shelf.books.add(self.books[8])
- self.assertEqual(list(shelf.books.all()), books + [self.books[8]])
-
- shelf.books = []
- self.assertEqual(list(shelf.books.all()), [])
-
- shelf.books = [self.books[9]]
- self.assertEqual(list(shelf.books.all()), [
- self.books[9]])
-
- shelf.books = []
- self.assertEqual(list(shelf.books.all()), [])
-
- def test_remove_items(self):
- shelf = self.model.objects.create()
- shelf.books = self.books[2:5]
- self.assertEqual(list(shelf.books.all()), [
- self.books[2],
- self.books[3],
- self.books[4]])
-
- shelf.books.remove(self.books[3])
- self.assertEqual(list(shelf.books.all()), [
- self.books[2],
- self.books[4]])
-
- shelf.books.remove(self.books[2], self.books[4])
- self.assertEqual(list(shelf.books.all()), [])
-
-# def test_add_relation_by_hand(self):
-# shelf = self.model.objects.create()
-# shelf.books = self.books[2:5]
-# self.assertEqual(list(shelf.books.all()), [
-# self.books[2],
-# self.books[3],
-# self.books[4]])
-#
-# shelf.books.create()
-# self.assertEqual(list(shelf.books.all()), [
-# self.books[2],
-# self.books[3],
-# self.books[4]])
-
-
-class TestStringReference(TestSortedManyToManyField):
- '''
- Test the same things as ``TestSortedManyToManyField`` but using a model
- that using a string to reference the relation where the m2m field should
- point to.
- '''
- model = Store
-
-
-class SortedForm(forms.Form):
- values = SortedMultipleChoiceField(
- queryset=Book.objects.all(),
- required=False)
-
-class TestSortedFormField(TestCase):
- def setUp(self):
- self.books = [Book.objects.create(name=c) for c in 'abcdefghik']
-
- def test_empty_field(self):
- form = SortedForm({'values': []})
- self.assertTrue(form.is_valid())
- self.assertFalse(form.cleaned_data['values'])
-
- def test_sorted_field_input(self):
- form = SortedForm({'values': [4, 2, 9]})
- self.assertTrue(form.is_valid())
- self.assertEqual(list(form.cleaned_data['values']), [
- self.books[3],
- self.books[1],
- self.books[8]])
-
- form = SortedForm({'values': [book.pk for book in self.books[::-1]]})
- self.assertTrue(form.is_valid())
- self.assertEqual(list(form.cleaned_data['values']), self.books[::-1])
-
- def test_form_field_on_model_field(self):
- class ShelfForm(forms.ModelForm):
- class Meta:
- model = Shelf
-
- form = ShelfForm()
- self.assertTrue(
- isinstance(form.fields['books'], SortedMultipleChoiceField))
-
- class MessyStoreForm(forms.ModelForm):
- class Meta:
- model = MessyStore
-
- form = MessyStoreForm()
- self.assertFalse(
- isinstance(form.fields['books'], SortedMultipleChoiceField))
- self.assertTrue(
- isinstance(form.fields['books'], forms.ModelMultipleChoiceField))