Created
July 21, 2012 22:29
-
-
Save cyface/3157428 to your computer and use it in GitHub Desktop.
Django Many-To-Many Create With Intermediary (Through) Table
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% extends "base.html" %} | |
{% block content %} | |
<section title="Child Create" data-role="content"> | |
<h2>Child Create</h2> | |
<form action="{% url child_create slug=form.family_slug.value %}" method="POST"> | |
{{ form.errors }} | |
{% csrf_token %} | |
<ul> | |
{{ form.as_ul }} | |
</ul> | |
<input type="submit" name="Submit" value="Submit"> | |
</form> | |
</section> | |
{% endblock %} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Django M2M With Through Example Forms""" | |
from models import WeaveStep, Step, Weave | |
from django.forms import ModelForm, HiddenInput, IntegerField, CharField | |
from django.contrib.auth.models import User | |
class ChildEditForm(ModelForm): | |
"""Form to Edit a Child and Specify the Ordering and Relation to Family""" | |
family_slug = CharField(widget=HiddenInput()) # Pointer Back to Family | |
order = IntegerField(required=False, widget=HiddenInput(), initial=0) | |
class Meta(): | |
model = Child | |
exclude = ['families',] | |
def save(self, commit=True): | |
child = super(ChildEditForm, self).save() # Save the child so we have an ID for the m2m | |
family_slug = self.cleaned_data.get('family_slug') | |
family = Family.objects.get(slug=family_slug) | |
order = self.cleaned_data.get('order') | |
FamilyChild.objects.create(family=family, child=child, order=order) | |
return child |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Django M2M With Through Example Models""" | |
import datetime | |
from django.db import models | |
class Child(models.Model): | |
"""Each Child can have multiple families.""" | |
name = models.CharField(max_length=120) | |
families = models.ManyToManyField('Parent', through='FamilyChild') | |
class Family(models.Model): | |
"""Families are groups of children in a particular order.""" | |
slug = models.SlugField(max_length=255) | |
children = models.ManyToManyField('Child', through='FamilyChild') | |
class FamilyChild(models.Model): | |
"""A FamilyChild is the many-to-many intersection of Families and Children""" | |
child = models.ForeignKey('Child', related_name='children') | |
family = models.ForeignKey('Family', related_name='families') | |
order = models.IntegerField(default=0) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Django M2M With Through Example URLs""" | |
from django.conf.urls import patterns, url | |
from views import ChildAdd | |
urlpatterns = patterns('', | |
# Child Create | |
url(r'^family/(?P<slug>[-_\w]+)/add/child/$', ChildAdd.as_view(), name="child_create"), | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Django M2M With Through Example Views""" | |
from django.views.generic import CreateView | |
from models import Child, Family | |
from forms import ChildEditForm | |
class ChildAdd(CreateView): | |
""" | |
View to add a child to a family | |
url: /family/<family-slug>/add/child | |
""" | |
model = Child | |
form_class = ChildEditForm | |
context_object_name = 'child' | |
template_name = 'child_create.html' | |
def get_initial(self): | |
"""Calculate Initial Data for the form, validate ownership of family""" | |
family_slug = self.kwargs.get('slug', self.request.POST.get('slug')) | |
family = get_object_or_404(Family, slug=family_slug) | |
return {'family_slug': family_slug} |
Hi, I would like to know how are you using the order filed in the through table(FamilyChild).
My question and curiosity is how do we get the list of child in the order mentioned in the FamilyChild model. It would help me understand the extra filed in the model, am new to Django. Expecting something like this.
child1 = Child.create(name='first_child')
child2 = Child.create(name='second_child')
family = Family.create(name='sample_family_name')
family.children.create(child=child1, order=1)
family.children.create(child=child2, order=2)
Now?
family.childrens.order_by(:order) ===> something like. How do we do ? Am from rails background new to django.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
am getting a Noreversematch for the url {% url child_create slug=form.family_slug.value %}"
basically i have this child_create under an app
main urls.py
url(r'^samrunbook/', include('samrunbook.urls')),
samrunbook/urls.py
So, if I understand correctly, account_create will be e.g sam/8/add/account, but it won't be resolved unless the urls start with
samrunbook/sam/8/add/account
Can you please help how to resolve this issue?.