Ticket #8648: 8648.diff
File 8648.diff, 4.9 KB (added by , 16 years ago) |
---|
-
django/db/models/fields/related.py
686 686 setattr(cls, related.get_accessor_name(), ForeignRelatedObjectsDescriptor(related)) 687 687 688 688 def formfield(self, **kwargs): 689 defaults = {'form_class': forms.ModelChoiceField, 'queryset': self.rel.to._default_manager.complex_filter(self.rel.limit_choices_to)} 689 defaults = { 690 'form_class': forms.ModelChoiceField, 691 'queryset': self.rel.to._default_manager.complex_filter( 692 self.rel.limit_choices_to), 693 'to_field_name': self.rel.field_name, 694 } 690 695 defaults.update(kwargs) 691 696 return super(ForeignKey, self).formfield(**defaults) 692 697 -
django/forms/models.py
460 460 if self.field.cache_choices: 461 461 if self.field.choice_cache is None: 462 462 self.field.choice_cache = [ 463 (obj.pk, self.field.label_from_instance(obj)) 464 for obj in self.queryset.all() 463 self.choice(obj) for obj in self.queryset.all() 465 464 ] 466 465 for choice in self.field.choice_cache: 467 466 yield choice 468 467 else: 469 468 for obj in self.queryset.all(): 470 yield (obj.pk, self.field.label_from_instance(obj))469 yield self.choice(obj) 471 470 471 def choice(self, obj): 472 if self.field.to_field_name: 473 key = getattr(obj, self.field.to_field_name) 474 else: 475 key = obj.pk 476 return (key, self.field.label_from_instance(obj)) 477 478 472 479 class ModelChoiceField(ChoiceField): 473 480 """A ChoiceField whose choices are a model QuerySet.""" 474 481 # This class is a subclass of ChoiceField for purity, but it doesn't … … 480 487 481 488 def __init__(self, queryset, empty_label=u"---------", cache_choices=False, 482 489 required=True, widget=None, label=None, initial=None, 483 help_text=None, *args, **kwargs):490 help_text=None, to_field_name=None, *args, **kwargs): 484 491 self.empty_label = empty_label 485 492 self.cache_choices = cache_choices 486 493 … … 490 497 *args, **kwargs) 491 498 self.queryset = queryset 492 499 self.choice_cache = None 500 self.to_field_name = to_field_name 493 501 494 502 def _get_queryset(self): 495 503 return self._queryset … … 532 540 if value in EMPTY_VALUES: 533 541 return None 534 542 try: 535 value = self.queryset.get(pk=value) 543 key = self.to_field_name or 'pk' 544 value = self.queryset.get(**{key: value}) 536 545 except self.queryset.model.DoesNotExist: 537 546 raise ValidationError(self.error_messages['invalid_choice']) 538 547 return value -
tests/modeltests/model_forms/models.py
120 120 class ArticleStatus(models.Model): 121 121 status = models.CharField(max_length=2, choices=ARTICLE_STATUS_CHAR, blank=True, null=True) 122 122 123 class Inventory(models.Model): 124 barcode = models.PositiveIntegerField(unique=True) 125 parent = models.ForeignKey('self', to_field='barcode', blank=True, null=True) 126 name = models.CharField(blank=False, max_length=20) 127 128 def __unicode__(self): 129 return self.name 130 123 131 __test__ = {'API_TESTS': """ 124 132 >>> from django import forms 125 133 >>> from django.forms.models import ModelForm, model_to_dict … … 1152 1160 ... 1153 1161 ValidationError: [u'Select a valid choice. z is not one of the available choices.'] 1154 1162 1163 # Foreign keys which use to_field ############################################# 1164 1165 >>> apple = Inventory.objects.create(barcode=86, name='Apple') 1166 >>> pear = Inventory.objects.create(barcode=22, name='Pear') 1167 >>> core = Inventory.objects.create(barcode=87, name='Core', parent=apple) 1168 1169 >>> field = ModelChoiceField(Inventory.objects.all(), to_field_name='barcode') 1170 >>> for choice in field.choices: 1171 ... print choice 1172 (u'', u'---------') 1173 (86, u'Apple') 1174 (22, u'Pear') 1175 (87, u'Core') 1176 1177 >>> class InventoryForm(ModelForm): 1178 ... class Meta: 1179 ... model = Inventory 1180 >>> form = InventoryForm(instance=core) 1181 >>> print form['parent'] 1182 <select name="parent" id="id_parent"> 1183 <option value="">---------</option> 1184 <option value="86" selected="selected">Apple</option> 1185 <option value="22">Pear</option> 1186 <option value="87">Core</option> 1187 </select> 1188 1189 >>> data = model_to_dict(core) 1190 >>> data['parent'] = '22' 1191 >>> form = InventoryForm(data=data, instance=core) 1192 >>> core = form.save() 1193 >>> core.parent 1194 <Inventory: Pear> 1155 1195 """}