mirror of
https://github.com/django/django.git
synced 2025-08-03 10:34:04 +00:00
Fixed #2445 -- Allowed limit_choices_to attribute to be a callable.
ForeignKey or ManyToManyField attribute ``limit_choices_to`` can now be a callable that returns either a ``Q`` object or a dict. Thanks michael at actrix.gen.nz for the original suggestion.
This commit is contained in:
parent
a718fcf201
commit
eefc88feef
15 changed files with 228 additions and 29 deletions
|
@ -8,6 +8,7 @@ words, most of these tests should be rewritten.
|
|||
"""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
|
@ -71,7 +72,6 @@ class Article(models.Model):
|
|||
status = models.PositiveIntegerField(choices=ARTICLE_STATUS, blank=True, null=True)
|
||||
|
||||
def save(self):
|
||||
import datetime
|
||||
if not self.id:
|
||||
self.created = datetime.date.today()
|
||||
return super(Article, self).save()
|
||||
|
@ -329,3 +329,21 @@ class CustomErrorMessage(models.Model):
|
|||
def clean(self):
|
||||
if self.name1 == 'FORBIDDEN_VALUE':
|
||||
raise ValidationError({'name1': [ValidationError('Model.clean() error messages.')]})
|
||||
|
||||
|
||||
def today_callable_dict():
|
||||
return {"last_action__gte": datetime.datetime.today()}
|
||||
|
||||
|
||||
def today_callable_q():
|
||||
return models.Q(last_action__gte=datetime.datetime.today())
|
||||
|
||||
|
||||
class Character(models.Model):
|
||||
username = models.CharField(max_length=100)
|
||||
last_action = models.DateTimeField()
|
||||
|
||||
|
||||
class StumpJoke(models.Model):
|
||||
most_recently_fooled = models.ForeignKey(Character, limit_choices_to=today_callable_dict, related_name="+")
|
||||
has_fooled_today = models.ManyToManyField(Character, limit_choices_to=today_callable_q, related_name="+")
|
||||
|
|
|
@ -22,7 +22,8 @@ from .models import (Article, ArticleStatus, BetterWriter, BigInt, Book,
|
|||
DerivedPost, ExplicitPK, FlexibleDatePost, ImprovedArticle,
|
||||
ImprovedArticleWithParentLink, Inventory, Post, Price,
|
||||
Product, TextFile, Writer, WriterProfile, Colour, ColourfulItem,
|
||||
ArticleStatusNote, DateTimePost, CustomErrorMessage, test_images)
|
||||
ArticleStatusNote, DateTimePost, CustomErrorMessage, test_images,
|
||||
StumpJoke, Character)
|
||||
|
||||
if test_images:
|
||||
from .models import ImageFile, OptionalImageFile
|
||||
|
@ -521,6 +522,12 @@ class FieldOverridesTroughFormMetaForm(forms.ModelForm):
|
|||
}
|
||||
|
||||
|
||||
class StumpJokeForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = StumpJoke
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class TestFieldOverridesTroughFormMeta(TestCase):
|
||||
def test_widget_overrides(self):
|
||||
form = FieldOverridesTroughFormMetaForm()
|
||||
|
@ -1921,3 +1928,34 @@ class ModelFormInheritanceTests(TestCase):
|
|||
self.assertEqual(list(type(str('NewForm'), (ModelForm, Mixin, Form), {})().fields.keys()), ['name'])
|
||||
self.assertEqual(list(type(str('NewForm'), (ModelForm, Form, Mixin), {})().fields.keys()), ['name', 'age'])
|
||||
self.assertEqual(list(type(str('NewForm'), (ModelForm, Form), {'age': None})().fields.keys()), ['name'])
|
||||
|
||||
|
||||
class LimitChoicesToTest(TestCase):
|
||||
"""
|
||||
Tests the functionality of ``limit_choices_to``.
|
||||
"""
|
||||
def setUp(self):
|
||||
self.threepwood = Character.objects.create(
|
||||
username='threepwood',
|
||||
last_action=datetime.datetime.today() + datetime.timedelta(days=1),
|
||||
)
|
||||
self.marley = Character.objects.create(
|
||||
username='marley',
|
||||
last_action=datetime.datetime.today() - datetime.timedelta(days=1),
|
||||
)
|
||||
|
||||
def test_limit_choices_to_callable_for_fk_rel(self):
|
||||
"""
|
||||
A ForeignKey relation can use ``limit_choices_to`` as a callable, re #2554.
|
||||
"""
|
||||
stumpjokeform = StumpJokeForm()
|
||||
self.assertIn(self.threepwood, stumpjokeform.fields['most_recently_fooled'].queryset)
|
||||
self.assertNotIn(self.marley, stumpjokeform.fields['most_recently_fooled'].queryset)
|
||||
|
||||
def test_limit_choices_to_callable_for_m2m_rel(self):
|
||||
"""
|
||||
A ManyToMany relation can use ``limit_choices_to`` as a callable, re #2554.
|
||||
"""
|
||||
stumpjokeform = StumpJokeForm()
|
||||
self.assertIn(self.threepwood, stumpjokeform.fields['has_fooled_today'].queryset)
|
||||
self.assertNotIn(self.marley, stumpjokeform.fields['has_fooled_today'].queryset)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue