Why Django want to alter table with proxy model? - python

I'm using Django 1.8, Python 2.7.15. Junior dev.
I created a model Test with many to many field to Django Group model:
class Test(models.Model):
group = models.ManyToManyField(Group)
I've made a migration, my project was working, all was good.
Now I had to create Group's proxy model with specyfic managers:
class ExtendedGroup(Group):
get_all = AllGroupsManager()
objects = DefaultGroupManager()
class Meta:
proxy = True
And I had to change my Test model group field (is has methods that must use new managers... so I have to use ExtendedGroup):
I'm changing ManyToManyField relation from Group to ExtendedGroup.
class Test(models.Model):
group = models.ManyToManyField(ExtendedGroup)
ExtendedGroup is proxy model so I think Test's group field should be related to Group even if I use ExtendedGroup (becouse it is proxy model).
But when I run server I got ProgrammingError:
column test_test_group.extendedgroup_id does not exist
When I "makemigrations" I can see that Django want to Alter group field with new relation to model (ExtendedGroup) that actually does not have any tables in database becouse it is proxy model.
operations = [
migrations.AlterField(
model_name='test',
name='group',
field=models.ManyToManyField(to='mainpage.ExtendedGroup'),
),
]
What is going here? Is it right? Why Django want to create relation to model that does not have any tables?
I just don't understand it.
I will appreciate any help!
EDIT:
When I run migration (migrate) I get a bunch of errors:
AttributeError: 'ManyToManyField' object has no attribute
'm2m_reverse_field_name'
So it does not work :(

Related

In Django, when trying to access a model's 1:1 relation that doesn't exist, sometime that relation is None, and sometimes it raises an exception. Why?

I noticed while debugging a Django application that with two tables with a 1:1 relation, trying to access the related object from the table that defines the 1:1 relation would return None, while trying to access the same nonexistent relation from the table that does not define the relation Django will raise a Model1.model2.RelatedObjectDoesNotExist exception. I was confused by this behavior as the same action has two different results on objects on the same type of relation.
This is an example of the models used:
class RelatedModel(models.Model):
pass
class RelationshipDefiner(models.Model):
related_object = models.OneToOneField(
RelatedModel,
on_delete=models.CASCADE,
related_name="relationship_definer",
blank=True,
null=True
)
This is an example of trying to print the relations to screen:
relationship_definer = RelationshipDefiner.objects.create()
related_object = RelatedModel.objects.create()
print("RELATIONSHIP DEFINER'S RELATED OBJECT:")
print(relationship_definer.related_object)
print("RELATED OBJECT'S RELATIONSHIP DEFINER:")
print(related_object.relationship_definer)
And the output:
RELATIONSHIP DEFINER'S RELATED OBJECT:
None
RELATED OBJECT'S RELATIONSHIP DEFINER:
Internal Server Error: /test/
File "/django/app/views/test.py", line 17, in test
print(related_object.relationship_definer)
app.models.sample.RelatedModel.relationship_definer.RelatedObjectDoesNotExist: RelatedModel has no relationship_definer.
Why do 1:1 nullable relationships behave differently on either side of the relation, and is there a way to coerce Django to behave consistently across both sides of the relationship?

Peewee and Flask-Admin: View with only foreign keys missing attribute '_data'

I use flask peewee together with flask-admin and it works fine for some model classes, but I got one model, that it does not work on and gives me the following error:
AttributeError: 'GroupMember' object has no attribute '_data'
This is how the model looks:
class GroupMember(BaseModel):
group = ForeignKeyField(Group)
member = ForeignKeyField(Member)
class Meta:
primary_key = CompositeKey('group', 'member')
As this model consists of only foreign keys, I thought I would need to create a custom view that lists the columns explicitly, because by default flask-admin hides those columns.
I did so:
class MyModelView(ModelView):
column_list = ('group', 'member')
And initialized the view:
admin.add_view(MyModelView(GroupMember))
This honestly changed nothing and I still get the same error. I found related questions that mentioned "backrefs" - what would that do and how would I do this? Or is this even the reason for my problem?

how to create a relation model with forms?

Hey i need to create a model from form. It's different way if i need to create a some another model, that have a relations with created object model from form. its must work like that -> i come on site, get form for create a model object and save new object. an then -> i have another model with relations with model from form. and i need, to create relation model object automaticly - when django taked new object from forms.
tried any can help me. i make it this way, but this time i have problem. -> i have manytomany field in my relation model, and i have manytomany field ->users from form. and i cant create a relation model with this instance :( Traceback:
TypeError at /ru/center/add/
Direct assignment to the forward side of a many-to-many set is prohibited. Use users_center.set() instead.
but i tired to try it(( help please, how i may do it?
views.py
for x in form['users_center'].data:
name_center = form['name_center'].data
fullname_center = form['fullname_center'].data
ogrn = form['ogrn_center'].data
head_center = form['head_center'].data # user id
many_users = form['users_center'].data
user_center = x # user id
new_center = Center.objects.create(name_center=name_center,
fullname_center=fullname_center,
ogrn_center=ogrn,
head_center=User.objects.get(id=head_center),
users_center=User.objects.get(id=int(x)))
new_center.save()
models.py
users_center = models.ManyToManyField(User,
related_name='center',
# through=CenterDetails,
default=None, blank=True,
verbose_name=_("Сотрудники"))
There is a join table implied by the many-to-many relationship between two models. The error is letting you know that you must set the relationship after creating a User object instead of trying to assign the relationship while creating the User object. You can use set() or add() to do this.
So try doing:
new_center = Center.objects.create(
name_center=name_center,
fullname_center=fullname_center,
ogrn_center=ogrn,
head_center=User.objects.get(id=head_center),
)
users_center=User.objects.get(id=int(x))
new_center.users_center.add(users_center)
Additionally it may be useful to rename your many to many field as a plural to indicate the relationship. Maybe users_centers instead. Since it seems like users can have many centers, and centers can have many users. That's up to you though, not required for it to work.

Fields clash in case of inheritance

I' ve the following simplified model structure:
#common/models.py
class CLDate(models.Model):
active = models.BooleanField(default=True)
last_modified = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
#br/models.py
class Dokument(CLDate):
user = models.ForeignKey(User)
class Entity(CLDate):
dokument = models.ForeignKey(Dokument)
. Both class inherits from CLDate, and i' ve a OneToMany relation between them. When i try to migrate, i got the following error:
python manage.py makemigrations
SystemCheckError: System check identified some issues:
ERRORS:
br.Entity.dokument: (models.E006) The field 'dokument' clashes with the
field 'dokument' from model 'common.cldate'.
I can' t really get why is this structure a problem for Django hence the Entity is a totally different object than the Dokument. Could anyone explain me why, and how could i solve it with this structure? So both should inherit from CLDate and there should be this kind of relation between the 2 models from the br application.
I also tried to delete all the migration files, and solve it that way, but the same. Runserver gives also this error.
Django: 1.11.2
Python: 3.4.2
Debian: 8.8
.
Thanks.
If i rename the dokument property name in the Entity model, it works fine.
I' m also almost pretty the same layout was working previously (in previous Django versions).
Since you are using multi-table inheritance, Django creates an implicit one-to-one field from Dokument to CLDate. The reverse relation dokument from CLDate to Dokument is clashing with your Entity.dokument field.
If you don't want to rename your Entity.dokument field, then your other option is to explicitly define the parent link field from Dokument to CLDate and set related_name.
class Dokument(CLDate):
cl_date = models.OneToOneField(CLDate, parent_link=True, related_name='related_dokument')
user = models.ForeignKey(User)

Django reverse lookup by ForeignKey

I have a django project which has two apps, one is AppA and AppB. Now AppA has a model
ModelA which is referenced by the model ModelB in AppB, using modelA = models.ForeignKey(ModelA, related_name='tricky')
Now in my view for AppA, when it shows ModelA, I do a get_object_or_404(ModelA, pk=prim_id). Then I want to get all the ModelBs which have a Foreign Key pointing to ModelA.
Documentation says I should do a mb = ModelB.objects.get(pk=prim_id) then mb.modela_set.all()
But, it failed on the mb.modela_set, and it says "ModelB object has no attribute 'suchsuch'". Notice I added the related_name field to ForeignKey, so I tried with that as well, including mb.tricky.all() and mb.tricky_set.all() to no avail.
Oh, and I have specified a different manager for AppA where I do objects = MyManager() which returns the normal query but with a filter applied.
What could be the problem? What is the prefered way to get the ModelBs referencing ModelA?
If the ForeignKey is, as you describe in ModelB and you do mb = ModelB.objects.get(pk=prim_id) then the look up for the modela attribute is not a reverse lookup. you simply access the related object via mb.modela!

Categories