Opened 5 years ago

Closed 4 years ago

Last modified 3 years ago

#13668 closed (fixed)

ManyToManyField passes ModelBase to router.db_for_write

Reported by: craig.kimerer@… Owned by: dgouldin
Component: Database layer (models, ORM) Version: 1.2
Severity: Keywords:
Cc: dgouldin@… Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

When using a ManyToMany field without the through parameter, the incorrect model type is passed into the router functions.

Consider the following example:

Models:

from django.db import models

class A(models.Model):
  asdf = models.CharField(max_length=10)
  
class B(models.Model):
  b = models.CharField(max_length=10)
  asdfs = models.ManyToManyField('A')

Router:

class MyRouter(object):
  
  def db_for_write(self, model, **hints):
    if model._meta.app_label == 'model_app_label':
      return 'not_default'
  
  def db_for_read(self, model, **hints):
    if model._meta.app_label == 'model_app_label'
      return 'not_default'
      
  def allow_relation(self, obj1, obj2, **hints):
    return obj1._state.db == obj2._state.db
      
  def allow_syncdb(self, db, model):
    if db == 'not_default' and model._meta.app_label == 'model_app_label':
      return True
    if db == 'default' and model._meta.app_label == 'model_app_label':
      return False
    return None

Running the following bit of code:

      aa = A.objects.create(asdf='1')
      bb = B.objects.create(b='asdf')
      bb.asdfs.add(aa)

I get an error about how the intermediary table model_app_label_b_asdfs on the default database does not exist

Attachments (1)

13668.diff (4.7 KB) - added by dgouldin 4 years ago.

Download all attachments as: .zip

Change History (8)

comment:1 Changed 5 years ago by russellm

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

comment:2 Changed 4 years ago by dgouldin

  • Cc dgouldin@… added
  • Owner changed from nobody to dgouldin

Changed 4 years ago by dgouldin

comment:3 Changed 4 years ago by dgouldin

  • Has patch set

comment:4 Changed 4 years ago by mtredinnick

  • Triage Stage changed from Accepted to Ready for checkin

Looks good to me. Thanks.

comment:5 Changed 4 years ago by ramiro

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

(In [15185]) Fixed #13668 -- Corrected database router methods invocation for ManyToMany fields without through models. Thanks craig.kimerer for the report and David Gouldin for the fix.

This also adds tests for r14857.

comment:6 Changed 4 years ago by ramiro

(In [15186]) [1.2.X] Fixed #13668 -- Corrected database router methods invocation for ManyToMany fields without through models. Thanks craig.kimerer for the report and David Gouldin for the fix.

This also adds tests for r14857.

Backport of [15185] from trunk.

comment:7 Changed 3 years ago by jacob

  • milestone 1.3 deleted

Milestone 1.3 deleted

Note: See TracTickets for help on using tickets.
Back to Top