Ticket #182 (closed defect: fixed)
Improper handling of _bases
| Reported by: | ralf.gerlich@… | Owned by: | andrew |
|---|---|---|---|
| Priority: | major | Milestone: | 0.7 |
| Component: | migrations | Version: | 0.6-pre |
| Keywords: | meta bases typeerror inheritance | Cc: |
Description
I have the following model (shortened for better readability):
class Person(models.Model):
surname = models.CharField(max_length=60);
firstname = models.CharField(max_length=60);
class Pilot(Person):
is_instructor = models.BooleanField(default=False);
class Flight(models.Model):
# ...
attendants = models.ManyToManyField(Pilot, blank=True, related_name='attended_flights');
passengers = models.ManyToManyField(Person, blank=True, related_name='passenger_flights');
# ...
I want to migrate all pilots from the passengers field to the attendants field:
from south.db import db
from django.db import models
from logbook.models import *
class Migration:
no_dry_run = True;
def forwards(self, orm):
for pilot in orm.Pilot.objects.all():
for flight in pilot.passenger_flights.all():
pilot.attended_flights.add(flight);
pilot.passenger_flights.clear();
pilot.save();
def backwards(self, orm):
for pilot in orm.Pilot.objects.all():
for flight in pilot.attended_flights.all():
pilot.passenger_flights.add(flight);
pilot.attended_flights.clear();
pilot.save();
models = {
'logbook.flight': {
'attendants': ('models.ManyToManyField', ["orm['logbook.Pilot']"],
{'related_name': "'attended_flights'",
'blank': 'True'}),
'passengers': ('models.ManyToManyField', ["orm['logbook.Person']"],
{'related_name': "'passenger_flights'",
'blank': 'True'}),
},
'logbook.person': {
'firstname': ('models.CharField', [], {'max_length': '60'}),
'id': ('models.AutoField', [], {'primary_key': 'True'}),
'surname': ('models.CharField', [], {'max_length': '60'})
},
'logbook.pilot': {
'Meta': {'_bases': ["logbook.models.Person"]},
'is_instructor': ('models.BooleanField', [], {'default': 'False'}),
'person_ptr': ('models.OneToOneField', ["orm['logbook.Person']"], {})
}
}
complete_apps = ['logbook']
The line pilot.attended_flights.add(flight); gives me a TypeError? exception, saying that an object of type 'flight' is expected.
Examining the type of flight I get 'logbook.models.Flight', while the model associated with pilot.attended_flights is 'logbook.models.flight'.
Looking into the code at south/orm.py I find that the base-class for the classes generated by the fake ORM is loaded using ask_for_it_by_name, which resolves the base of Pilot to be logbook.models.Person, i.e. the real instead of the fake base.
As the passenger_flights-relation is defined in Person, the field definitions in the fake Person and the fake Pilot differ.
Fix: Use the fake base class instead.
Is there a way to work around this issue?
Attachments
Change History
comment:4 Changed 3 years ago by andrew
- Status changed from assigned to closed
- Resolution set to fixed
Fixed in [237ca3bb6d5d]. Finally :)

Yes, I should be able to use the fake bases, you're right.