I am new to Django (and programming in general) and could use help with something possible very simple but I can't figure it out.
Currently I am working on a Project Manager app in Django for my portfolio.
But I am stuck with creating list of the different project and their tasks.
I would like to create something like this:
Project_1
- task item 1 (of project_1)
- task item 2 (of project_1)
Project_2
- task item 1 (of project_2)
- task item 2 (of project_2)
Project_3
- task item 1 (of project_3)
- task item 2 (of project_3)
- task item 3 (of project_3)
Currently I have the following:
view.py:
def project(request):
""" Show all Projects"""
projects = Project.objects.order_by('date_added')
project = Project.objects.get(id=1)
tasks = project.task_set.order_by('date_added')
context = {'projects': projects, 'tasks': tasks}
return render(request, 'tasks/project.html', context)
project.html
{% extends "tasks/base.html" %}
{% block content %}
<p>Projects</p>
<ul>
{% for project in projects %}
<li>{{project}}</li>
<ul>
{% for task in tasks %}
<li>{{task}}</li>
{% empty %}
<li>No tasks added </li>
{% endfor %}
</ul>
{% empty %}
<li>No projects have been added yet.</li>
{% endfor %}
</ul>
{% endblock content %}
models.py
class Project(models.Model):
"""A project the user is working on."""
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
"""Return a string representation of the model."""
return self.text
class Task(models.Model):
"""A task of a project to complete."""
project = models.ForeignKey(Project, on_delete=models.CASCADE)
text = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = 'tasks'
def __str__(self):
"""Return a string representation of the model."""
if(len(self.text) < 50 ):
return f"{self.text}"
else:
return f"{self.text[:50]}..."
The result I get is:
Project_1
- task item 1 (of project_1)
- task item 2 (of project_1)
Project_2
- task item 1 (of project_1)
- task item 2 (of project_1)
Project_3
- task item 1 (of project_1)
- task item 2 (of project_1)
I know the issue is that I use project = Project.objects.get(id=1)
and because of this it only shows the tasks related to project one.
And I think if the id is related to the right project id this might be the solution.
I don't seem to find out how I do this. Or I might be looking in the wrong direction.
Any help is welcome, thanks for in advance.
You should be able to use the reverse lookup for the task from project. See this part of the django docs for it: https://docs.djangoproject.com/en/3.0/topics/db/queries/#following-relationships-backward
You have established a foreign key relationship from Tasks to Project. So one project has many tasks. You can access the tasks of a project using the reverse lookup using
project.task_set
reference. You can do this in the template as well. So your view would be simply:and the part in your template where you list the tasks should be:
Hope this helps, please let me know if anything needs to be clarified.