Comments (10)
Finally completed in #62!
from django-modelcluster.
I wrote a quick guide and explanation on how to implement M2M's using what's currently available. https://gist.github.com/alexgleason/09b1802b004babd74e96
from django-modelcluster.
This is affecting us us well, does anyone have any ideas on how to properly implement support for m2m relations?
from django-modelcluster.
@gasman Can you comment on this? Is the crux of the issue that modelcluster just wasn't designed to work with M2M's? Or is modelcluster accidentally overstepping its bounds when a Page has an M2M with a non-modelcluster model? If the latter, can you point the community in the right direction so we can help resolve this?
from django-modelcluster.
@jsma It's the first one I'm afraid - modelcluster isn't (currently) designed to work with M2M relations. I'm sure M2M support could be implemented, but it hasn't been a high priority up to now, because it's generally possible to work around it by defining your own 'through' models.
from django-modelcluster.
Hi guys,
I'm having a hard time trying to understand this line:
https://github.com/torchbox/django-modelcluster/blob/master/modelcluster/forms.py#L265
- Why the call to
save_m2m
only happens whencommit=False
? - Why not call
save_m2m
only whencommit=True
?
The last one seems to solve the problem with many-to-many relationships, but I'm not aware of the side effects of this change.
from django-modelcluster.
@caioariede When commit=True
, Django's own save
method deals with saving m2m relations, so we don't have to do it in our own code. In fact, save_m2m
is not even defined in that situation: https://github.com/django/django/blob/master/django/forms/models.py#L449-L456
from django-modelcluster.
So what's the purpose of calling it manually? I read the comment but didn't get it.
from django-modelcluster.
The overall principle of django-modelcluster is that you can assign relations between objects (e.g. band.members = [john, paul, george, ringo]
) and have it store those in memory, so that you can query those relations without them existing in the database. Django on its own does not support this - if you assign a relation like that, it will immediately try to write those objects to the database.
When you call form.save(commit=False)
, you are telling Django "copy the form data to the model, without saving it to the database". This creates a problem if the form data contains M2M relations, because Django can only represent those relations by saving them to the database. To work around this, Django just copies the plain (non-relation) fields to the model, and generates a save_m2m
method that you can call later, when you're ready to write your data back to the database.
With django-modelcluster, we don't need this workaround - we can write the relation data back to the model immediately on form.save(commit=False)
, because the relations will be stored in memory, not written back to the database. So, in this piece of code, django-modelcluster is effectively saying "Take the actions that Django has postponed to the save_m2m
method, and perform them now, because we know that we can safely do them without writing to the database".
from django-modelcluster.
I'm currently having a similar issue. Adding a manytomany to an existing element in the db works fine, but when trying to create a new one with wagtail Line 230 in forms.py causes an error, for example: "<Team: Red>" needs to have a value for field "team" before this many-to-many relationship can be used."
, the many-to-many in question being the "players" field.
I have no idea where "team" comes from, since I haven't defined it in my model anywhere, however if I comment out line 230, create a Team, and then uncomment it, I can edit the page and add players to the team just fine.
Here's some example code.
class Sport(Page):
description = RichTextField()
content_panels = Page.content_panels + [
FieldPanel('description', classname="full"),
]
class Team(Page):
team_game = models.ForeignKey(Sport, related_name='roster_game', on_delete=models.PROTECT) # the sport they play
players = models.ManyToManyField(User, blank=True) # linked to users, many users on a team
level = models.TextField() # the skill level of the team
content_panels = Page.content_panels + [
FieldPanel('roster_game', classname="full"),
FieldPanel('players'),
FieldPanel('level')
]
# practice
class Practice(Page):
practice_team = models.ForeignKey(Team, on_delete=models.PROTECT) # the team that is playing
times = models.TextField() # practice times
location = models.TextField() # practice location
content_panels = Page.content_panels + [
FieldPanel('practice_team', classname="full"),
FieldPanel('times'),
FieldPanel('location')
]
from django-modelcluster.
Related Issues (20)
- KeyError in a del HOT 8
- Copy fails for a Wagtail page with no tags HOT 7
- Multi table inheritance - ptr_id fields not being restored
- Using TaggedItem in ClusterTaggableManager causing AttributeError HOT 1
- Unable to `prefetch_related` on `ClusterTaggableManager` HOT 1
- When I Modify Elements via Admin Panel , Its not getting Saved HOT 1
- Add support for Django 3.2 HOT 3
- ClusterForm.as_p should return a safe string
- test suite fails with django-taggit >= 2.0.0 HOT 1
- Nested ClusterableModel relations are not copied HOT 1
- AttributeError when a ParentalKey related manager is used as the queryset for a ModelChoiceField HOT 3
- Wagtail 3.0 support planned? HOT 2
- GenericForeignKey
- Django 5.0 support HOT 1
- Filtering on related manager when using `prefetch_related` with explicit `queryset` on a ClusterableModel returns wrong results HOT 1
- Field with the same name as a lookup in `FILTER_EXPRESSION_TOKENS` causes crash when filtering with implicit `exact`
- test_formfield_callback failing with Django 4.2 HOT 1
- Docs: please provide an example of a through model with a ParentalManyToManyField
- Unhelpful messaging when model attribute name shadows child relation
- Preview breaks on latest 6.2 version HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from django-modelcluster.