I have two models with One to Many relationship. The Models are Parent and Child respectively. I have managed to dynamically render data from the Parent Model, but now I want to be able to put a link to to each Parent Record, such that when clicked it will create a Child record and render out the child information to the respective parent.
#Models
class Parent(models.Model):
surname = models.CharField(max_length=150, null=False, blank=False)
first_name = models.CharField(max_length=150, null=False, blank=False)
class Child(models.Model):
parent = models.ForeignKey(Parent, null=True, blank=True, on_delete=SET_NULL)
first_name = models.CharField(max_length=50, null=False, blank=False)
last_name = models.CharField(max_length=50, null=False, blank=False)
views.py
def display(request, pk):
parents = Parent.objects.get(id=pk)
child = parents.child_set.all()
context = {'parents':parents, 'child':child}
return render(request, 'reg/info_page.html', context)
I have tried to implement the reverse relation but when I try to display the child's information, it comes up blank.
div >
<p >Child Name</p>
<h1>{{child.first_name}}</h1> </div>
CodePudding user response:
Have a closer look at the QuerySet's all() method. It returns a copy of the QuerySet instance, so what you get is basically a list like object.
When you write child = parents.child_set.all()
and pass child
to the template renderer, you are actually passing a list of child objects. To properly display them in the template, you thus need to loop over this list which could look something like this:
<ul>
{% for a_child in child %}
<li>{{ a_child.first_name }}</li>
{% endfor %}
</ul>
Hopefully that clarified things a little.
As to the 2nd part, about how to add a child directly in the parent view. This is a different question, really.
I would suggest to write a custom CreateView for Child
, something like:
class AddChild(CreateView):
model = Child
def form_valid(self, form):
form.instance.parent_id = self.kwargs.get('pk')
return super(AddChild, self).form_valid(form)
and add a link to this view on the parent's page, something like 'create child', that sends the id of the parent along with the request.
If you do not want to leave the parent's view, you could make a popup form. There is a good SO answer already about how to do that.