Opened 6 years ago

Closed 5 years ago

#11662 closed (worksforme)

Filtered Queryset update() on a Proxy Model updates all records

Reported by: stryderjzw Owned by: nobody
Component: Database layer (models, ORM) Version: 1.1
Severity: Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

Here's my models:

class Item(models.Model):
    ...

class Bid(models.Model):
    ...
    item = models.ForeignKey(Item)
    processed = models.BooleanField(default=False)
    ...

class Transaction(Bid):
    class Meta:
        proxy = True  

When I run:

Transaction.objects.filter(processed=False, item=2).update(processed=True)

It would set all Transactions.processed to True, when I clearly only want the bids on item 2 to be processed.

I get this SQL:

{'time': '0.000', 'sql': 'UPDATE "game_bid" SET "processed" = true'}

However:

Bid.objects.filter(processed=False, item=2).update(processed=True)

This appears to work as intended.

SQL:

{'time': '0.000', 'sql': 'UPDATE "game_bid" SET "processed" = true WHERE ("game_bid"."item_id" = 6 AND "game_bid"."processed" = false }

Change History (2)

comment:1 Changed 6 years ago by Alex

  • Component changed from Uncategorized to Database layer (models, ORM)
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

comment:2 Changed 5 years ago by emulbreh

  • Resolution set to worksforme
  • Status changed from new to closed

I cannot reproduce this with r11638 on sqlite.

import unittest
from django.db import models, connection
from django.conf import settings

class Item(models.Model):
    pass

class Bid(models.Model):
    item = models.ForeignKey(Item)
    processed = models.BooleanField(default=False)

class Transaction(Bid):
    class Meta:
        proxy = True
    
class Tests(unittest.TestCase):
    def test_11662(self):
        item1 = Item.objects.create(id=1)
        item2 = Item.objects.create(id=2)
        
        Bid.objects.create(item=item1)
        Bid.objects.create(item=item2)

        Transaction.objects.filter(processed=False, item=item2).update(processed=True)
        self.assertEqual(Bid.objects.get(item=item1).processed, False)
        
Note: See TracTickets for help on using tickets.
Back to Top