Changeset 8823
- Timestamp:
- 09/01/08 17:43:38 (3 months ago)
- Files:
-
- django/trunk/django/contrib/admin/templatetags/admin_list.py (modified) (1 diff)
- django/trunk/django/contrib/admin/views/main.py (modified) (2 diffs)
- django/trunk/django/contrib/admin/widgets.py (modified) (8 diffs)
- django/trunk/django/db/models/fields/related.py (modified) (1 diff)
- django/trunk/django/forms/models.py (modified) (5 diffs)
- django/trunk/tests/modeltests/model_forms/models.py (modified) (4 diffs)
- django/trunk/tests/regressiontests/admin_widgets/models.py (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/contrib/admin/templatetags/admin_list.py
r8388 r8823 223 223 # Convert the pk to something that can be used in Javascript. 224 224 # Problem cases are long ints (23L) and non-ASCII strings. 225 result_id = repr(force_unicode(getattr(result, pk)))[1:] 225 if cl.to_field: 226 attr = str(cl.to_field) 227 else: 228 attr = pk 229 result_id = repr(force_unicode(getattr(result, attr)))[1:] 226 230 yield mark_safe(u'<%s%s><a href="%s"%s>%s</a></%s>' % \ 227 231 (table_tag, row_class, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %s); return false;"' % result_id or ''), conditional_escape(result_repr), table_tag)) django/trunk/django/contrib/admin/views/main.py
r8700 r8823 25 25 PAGE_VAR = 'p' 26 26 SEARCH_VAR = 'q' 27 TO_FIELD_VAR = 't' 27 28 IS_POPUP_VAR = 'pop' 28 29 ERROR_FLAG = 'e' … … 53 54 self.show_all = ALL_VAR in request.GET 54 55 self.is_popup = IS_POPUP_VAR in request.GET 56 self.to_field = request.GET.get(TO_FIELD_VAR) 55 57 self.params = dict(request.GET.items()) 56 58 if PAGE_VAR in self.params: 57 59 del self.params[PAGE_VAR] 60 if TO_FIELD_VAR in self.params: 61 del self.params[TO_FIELD_VAR] 58 62 if ERROR_FLAG in self.params: 59 63 del self.params[ERROR_FLAG] django/trunk/django/contrib/admin/widgets.py
r8764 r8823 42 42 class AdminDateWidget(forms.TextInput): 43 43 class Media: 44 js = (settings.ADMIN_MEDIA_PREFIX + "js/calendar.js", 44 js = (settings.ADMIN_MEDIA_PREFIX + "js/calendar.js", 45 45 settings.ADMIN_MEDIA_PREFIX + "js/admin/DateTimeShortcuts.js") 46 46 47 47 def __init__(self, attrs={}): 48 48 super(AdminDateWidget, self).__init__(attrs={'class': 'vDateField', 'size': '10'}) … … 50 50 class AdminTimeWidget(forms.TextInput): 51 51 class Media: 52 js = (settings.ADMIN_MEDIA_PREFIX + "js/calendar.js", 52 js = (settings.ADMIN_MEDIA_PREFIX + "js/calendar.js", 53 53 settings.ADMIN_MEDIA_PREFIX + "js/admin/DateTimeShortcuts.js") 54 54 55 55 def __init__(self, attrs={}): 56 56 super(AdminTimeWidget, self).__init__(attrs={'class': 'vTimeField', 'size': '8'}) 57 57 58 58 class AdminSplitDateTime(forms.SplitDateTimeWidget): 59 59 """ … … 87 87 def __init__(self, attrs={}): 88 88 super(AdminFileWidget, self).__init__(attrs) 89 89 90 90 def render(self, name, value, attrs=None): 91 91 output = [] … … 106 106 107 107 def render(self, name, value, attrs=None): 108 from django.contrib.admin.views.main import TO_FIELD_VAR 108 109 related_url = '../../../%s/%s/' % (self.rel.to._meta.app_label, self.rel.to._meta.object_name.lower()) 110 params = {} 109 111 if self.rel.limit_choices_to: 110 url = '?' + '&'.join(['%s=%s' % (k, ','.join(v)) for k, v in self.rel.limit_choices_to.items()])111 else:112 url = ''112 params.update(dict([(k, ','.join(v)) for k, v in self.rel.limit_choices_to.items()])) 113 params.update({TO_FIELD_VAR: self.rel.get_related_field().name}) 114 url = '?' + '&'.join(['%s=%s' % (k, v) for k, v in params.items()]) 113 115 if not attrs.has_key('class'): 114 116 attrs['class'] = 'vForeignKeyRawIdAdminField' # The JavaScript looks for this hook. … … 122 124 output.append(self.label_for_value(value)) 123 125 return mark_safe(u''.join(output)) 124 126 125 127 def label_for_value(self, value): 126 return ' <strong>%s</strong>' % \ 127 truncate_words(self.rel.to.objects.get(pk=value), 14) 128 128 key = self.rel.get_related_field().name 129 obj = self.rel.to.objects.get(**{key: value}) 130 return ' <strong>%s</strong>' % truncate_words(obj, 14) 131 129 132 class ManyToManyRawIdWidget(ForeignKeyRawIdWidget): 130 133 """ … … 134 137 def __init__(self, rel, attrs=None): 135 138 super(ManyToManyRawIdWidget, self).__init__(rel, attrs) 136 139 137 140 def render(self, name, value, attrs=None): 138 141 attrs['class'] = 'vManyToManyRawIdAdminField' … … 142 145 value = '' 143 146 return super(ManyToManyRawIdWidget, self).render(name, value, attrs) 144 147 145 148 def label_for_value(self, value): 146 149 return '' … … 153 156 return [value] 154 157 return None 155 158 156 159 def _has_changed(self, initial, data): 157 160 if initial is None: django/trunk/django/db/models/fields/related.py
r8814 r8823 692 692 693 693 def formfield(self, **kwargs): 694 defaults = {'form_class': forms.ModelChoiceField, 'queryset': self.rel.to._default_manager.complex_filter(self.rel.limit_choices_to)} 694 defaults = { 695 'form_class': forms.ModelChoiceField, 696 'queryset': self.rel.to._default_manager.complex_filter( 697 self.rel.limit_choices_to), 698 'to_field_name': self.rel.field_name, 699 } 695 700 defaults.update(kwargs) 696 701 return super(ForeignKey, self).formfield(**defaults) django/trunk/django/forms/models.py
r8822 r8823 551 551 if self.field.choice_cache is None: 552 552 self.field.choice_cache = [ 553 (obj.pk, self.field.label_from_instance(obj)) 554 for obj in self.queryset.all() 553 self.choice(obj) for obj in self.queryset.all() 555 554 ] 556 555 for choice in self.field.choice_cache: … … 558 557 else: 559 558 for obj in self.queryset.all(): 560 yield (obj.pk, self.field.label_from_instance(obj)) 559 yield self.choice(obj) 560 561 def choice(self, obj): 562 if self.field.to_field_name: 563 key = getattr(obj, self.field.to_field_name) 564 else: 565 key = obj.pk 566 return (key, self.field.label_from_instance(obj)) 567 561 568 562 569 class ModelChoiceField(ChoiceField): … … 571 578 def __init__(self, queryset, empty_label=u"---------", cache_choices=False, 572 579 required=True, widget=None, label=None, initial=None, 573 help_text=None, *args, **kwargs):580 help_text=None, to_field_name=None, *args, **kwargs): 574 581 self.empty_label = empty_label 575 582 self.cache_choices = cache_choices … … 581 588 self.queryset = queryset 582 589 self.choice_cache = None 590 self.to_field_name = to_field_name 583 591 584 592 def _get_queryset(self): … … 623 631 return None 624 632 try: 625 value = self.queryset.get(pk=value) 633 key = self.to_field_name or 'pk' 634 value = self.queryset.get(**{key: value}) 626 635 except self.queryset.model.DoesNotExist: 627 636 raise ValidationError(self.error_messages['invalid_choice']) django/trunk/tests/modeltests/model_forms/models.py
r8819 r8823 79 79 writer = models.OneToOneField(Writer, primary_key=True) 80 80 age = models.PositiveIntegerField() 81 81 82 82 def __unicode__(self): 83 83 return "%s is %s" % (self.writer, self.age) … … 138 138 status = models.CharField(max_length=2, choices=ARTICLE_STATUS_CHAR, blank=True, null=True) 139 139 140 140 class Inventory(models.Model): 141 barcode = models.PositiveIntegerField(unique=True) 142 parent = models.ForeignKey('self', to_field='barcode', blank=True, null=True) 143 name = models.CharField(blank=False, max_length=20) 144 145 def __unicode__(self): 146 return self.name 147 141 148 __test__ = {'API_TESTS': """ 142 149 >>> from django import forms … … 1136 1143 ... 1137 1144 ValidationError: [u'Enter only digits separated by commas.'] 1138 >>> f.clean(',,,,') 1145 >>> f.clean(',,,,') 1139 1146 u',,,,' 1140 1147 >>> f.clean('1.2') … … 1205 1212 ValidationError: [u'Select a valid choice. z is not one of the available choices.'] 1206 1213 1214 # Foreign keys which use to_field ############################################# 1215 1216 >>> apple = Inventory.objects.create(barcode=86, name='Apple') 1217 >>> pear = Inventory.objects.create(barcode=22, name='Pear') 1218 >>> core = Inventory.objects.create(barcode=87, name='Core', parent=apple) 1219 1220 >>> field = ModelChoiceField(Inventory.objects.all(), to_field_name='barcode') 1221 >>> for choice in field.choices: 1222 ... print choice 1223 (u'', u'---------') 1224 (86, u'Apple') 1225 (22, u'Pear') 1226 (87, u'Core') 1227 1228 >>> class InventoryForm(ModelForm): 1229 ... class Meta: 1230 ... model = Inventory 1231 >>> form = InventoryForm(instance=core) 1232 >>> print form['parent'] 1233 <select name="parent" id="id_parent"> 1234 <option value="">---------</option> 1235 <option value="86" selected="selected">Apple</option> 1236 <option value="22">Pear</option> 1237 <option value="87">Core</option> 1238 </select> 1239 1240 >>> data = model_to_dict(core) 1241 >>> data['parent'] = '22' 1242 >>> form = InventoryForm(data=data, instance=core) 1243 >>> core = form.save() 1244 >>> core.parent 1245 <Inventory: Pear> 1207 1246 """} django/trunk/tests/regressiontests/admin_widgets/models.py
r8277 r8823 6 6 class Member(models.Model): 7 7 name = models.CharField(max_length=100) 8 8 9 9 def __unicode__(self): 10 10 return self.name … … 13 13 name = models.CharField(max_length=100) 14 14 members = models.ManyToManyField(Member) 15 15 16 16 def __unicode__(self): 17 17 return self.name … … 21 21 name = models.CharField(max_length=100) 22 22 cover_art = models.FileField(upload_to='albums') 23 23 24 24 def __unicode__(self): 25 25 return self.name 26 27 class Inventory(models.Model): 28 barcode = models.PositiveIntegerField(unique=True) 29 parent = models.ForeignKey('self', to_field='barcode', blank=True, null=True) 30 name = models.CharField(blank=False, max_length=20) 31 32 def __unicode__(self): 33 return self.name 26 34 27 35 __test__ = {'WIDGETS_TESTS': """ … … 85 93 True 86 94 95 # Check that ForeignKeyRawIdWidget works with fields which aren't related to 96 # the model's primary key. 97 >>> apple = Inventory.objects.create(barcode=86, name='Apple') 98 >>> pear = Inventory.objects.create(barcode=22, name='Pear') 99 >>> core = Inventory.objects.create(barcode=87, name='Core', parent=apple) 100 >>> rel = Inventory._meta.get_field('parent').rel 101 >>> w = ForeignKeyRawIdWidget(rel) 102 >>> print w.render('test', core.parent_id, attrs={}) 103 <input type="text" name="test" value="86" class="vForeignKeyRawIdAdminField" /><a href="../../../admin_widgets/inventory/" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="/admin_media/img/admin/selector-search.gif" width="16" height="16" alt="Lookup" /></a> <strong>Apple</strong> 87 104 """ % { 88 105 'ADMIN_MEDIA_PREFIX': settings.ADMIN_MEDIA_PREFIX,
