Ticket #10922: formset.2.diff

File formset.2.diff, 3.5 KB (added by Alex Gaynor, 15 years ago)

fixed the SQL abuse, and code duplication, however if you take a look at the test I added a comment to it seems to be testing the exact behavior we want to avoid, guessing at the object

  • django/forms/models.py

    diff --git a/django/forms/models.py b/django/forms/models.py
    index 41380f2..d25f3c1 100644
    a b class BaseModelFormSet(BaseFormSet):  
    395395            return len(self.get_queryset())
    396396        return super(BaseModelFormSet, self).initial_form_count()
    397397
     398    def _construct_forms(self, *args, **kwargs):
     399        if self.is_bound:
     400            self._queryset_dict = dict([(o.pk, o) for o in self.get_queryset()])
     401        super(BaseModelFormSet, self)._construct_forms(*args, **kwargs)
     402        if self.is_bound:
     403            del self._queryset_dict
     404
    398405    def _construct_form(self, i, **kwargs):
    399         if i < self.initial_form_count():
     406        if self.is_bound and i < self.initial_form_count():
     407            pk = self.data["%s-%s" % (self.add_prefix(i), self.model._meta.pk.name)]
     408            pk_field = self.model._meta.pk
     409            pk = pk_field.get_db_prep_lookup('exact', pk)
     410            if isinstance(pk, list):
     411                pk = pk[0]
     412            kwargs['instance'] = self._queryset_dict.get(pk)
     413        if i < self.initial_form_count() and not kwargs.get('instance'):
    400414            kwargs['instance'] = self.get_queryset()[i]
    401415        return super(BaseModelFormSet, self)._construct_form(i, **kwargs)
    402416
    class BaseModelFormSet(BaseFormSet):  
    499513            return ((not pk.editable) or (pk.auto_created or isinstance(pk, AutoField))
    500514                or (pk.rel and pk.rel.parent_link and pk_is_editable(pk.rel.to._meta.pk)))
    501515        if pk_is_editable(pk):
    502             try:
    503                 pk_value = self.get_queryset()[index].pk
    504             except IndexError:
     516            if form.is_bound:
     517                pk_value = form.instance.pk
     518            else:
    505519                pk_value = None
    506520            if isinstance(pk, OneToOneField) or isinstance(pk, ForeignKey):
    507521                qs = pk.rel.to._default_manager.get_query_set()
  • tests/modeltests/model_formsets/models.py

    diff --git a/tests/modeltests/model_formsets/models.py b/tests/modeltests/model_formsets/models.py
    index f30b212..4c319f7 100644
    a b class CustomPrimaryKey(models.Model):  
    5858class Place(models.Model):
    5959    name = models.CharField(max_length=50)
    6060    city = models.CharField(max_length=50)
    61    
     61
    6262    def __unicode__(self):
    6363        return self.name
    6464
    class OwnerProfile(models.Model):  
    8585
    8686class Restaurant(Place):
    8787    serves_pizza = models.BooleanField()
    88    
     88
    8989    def __unicode__(self):
    9090        return self.name
    9191
    True  
    573573...     print book.title
    574574Les Fleurs du Mal
    575575
    576 Test inline formsets where the inline-edited object uses multi-table inheritance, thus 
     576Test inline formsets where the inline-edited object uses multi-table inheritance, thus
    577577has a non AutoField yet auto-created primary key.
    578578
    579579>>> AuthorBooksFormSet3 = inlineformset_factory(Author, AlternateBook, can_delete=False, extra=1)
    True  
    734734...     'ownerprofile-0-owner': u'1',
    735735...     'ownerprofile-0-age': u'55',
    736736... }
    737 >>> formset = FormSet(data, instance=owner)
     737>>> formset = FormSet(data, instance=owner) # this seems to be testing the behavior we want to avoid... hrm.
    738738>>> formset.is_valid()
    739739True
    740740>>> formset.save()
    741741[<OwnerProfile: Joe Perry is 55>]
    742742
    743 # ForeignKey with unique=True should enforce max_num=1 
     743# ForeignKey with unique=True should enforce max_num=1
    744744
    745745>>> FormSet = inlineformset_factory(Place, Location, can_delete=False)
    746746>>> formset = FormSet(instance=place)
Back to Top