My goal is to list the tag_titles for each note created.
I am having issues because the tag_title and note are linked through a Many to Many relationship.
How I would normally do this is:
{% for note_tag in note_tags %}
{% if note_tag.note == note %}
{{note_tag.tag_title}}
{% endif %}
{% endfor %}
However, because tag_title has a many to many relationship with NoteModel, note_tag.note gives out notes.NoteModel.None
My models.py are as follows:
class NoteModel(models.Model):
note = models.CharField(
max_length = 5000,
)
note_title = models.CharField(
max_length = 500,
blank = False,
null = True,
)
project = models.ForeignKey(
IndividualProject,
on_delete=models.CASCADE,
related_name = "note_projects",
blank = False,
null = True,
)
tag = models.ManyToManyField(
'NoteTagModel',
related_name="tags",
blank= False,
through = "TaggedModel"
)
def __str__(self):
return f"{self.note_title}"
class NoteTagModel(models.Model):
note = models.ManyToManyField(
'NoteModel',
related_name="tag_notes",
blank= False,
through = "TaggedModel"
)
tag_title = models.CharField(
max_length = 200,
default = "General",
)
def __str__(self):
return f"{self.tag_title}"
class TaggedModel(models.Model):
note = models.ForeignKey(NoteModel, on_delete = models.CASCADE)
tag = models.ForeignKey(NoteTagModel, on_delete = models.CASCADE)
def __str__(self):
return f"{self.note} | {self.tag}"
class TagCommentaryModel(models.Model):
tag_title = models.ForeignKey(
NoteTagModel,
on_delete=models.CASCADE,
related_name="tag",
blank = False,
null = True,
)
tag_commentary = models.CharField(
max_length = 5000
)
def __str__(self):
return f"Tag: {self.tag_title} | Tag Commentary: {self.tag_commentary}"
The context in my views.py is as follows:
context = {
'note_form' : note_form,
'notes' : NoteModel.objects.filter(project = obj),
'notes_tag' : NoteTagModel.objects.all(),
'commentary' : TagCommentaryModel.objects.all(),
'projects' : IndividualProject.objects.all(),
'specific_project' : IndividualProject.objects.get(id=id),
'obj' : IndividualProject.objects.get(id=id),
'tagged' : TaggedModel.objects.all(),
}
return render(request, "notes/specific-note.html", context)
My django template is as follows:
<div class = note_overview_container>
{% for note in notes %}
<div class = individual_note_container>
<div class = note_title>
{{ note.note_title }}
</div>
{% for note_tag in notes_tag %}
<div class = tag_title>
{{ note_tag.tag_title }}
</div>
<ul class = tag_commentary>
{% for commentary in commentary %}
{% if note_tag == commentary.tag_title %}
{% if note == commentary.note %}
<li>{{ commentary.tag_commentary }}</li>
{% endif %}
{% endif %}
{% endfor %}
</ul>
{% endfor %}
</div>
{% endfor %}
</div>
Any help would be greatly appreciated
CodePudding user response:
You can simplify your models a lot in my opinion. You point from tag in NoteModel to NoteTagModel and vice versa & I don’t think it is needed. Also TaggedModel seems superfluous. At least if there isn't a specific reason to link it like you did.
class NoteModel(models.Model):
note = models.CharField(max_length = 5000)
note_title = models.CharField(max_length=500, blank=False, null=True)
project = models.ForeignKey(IndividualProject, on_delete=models.CASCADE, related_name="note_projects", blank=False, null=True)
# plural
tags = models.ManyToManyField(NoteTagModel, related_name="tags", blank=False)
def __str__(self):
return self.note_title
class NoteTagModel(models.Model):
# usually there is no need to point here again to the same model thats already pointing to this one
tag_title = models.CharField(max_length=200, default="General")
def __str__(self):
return self.tag_title
If you want to access reverse from NoteTagModel to NoteModel, you can do the following eg:
for tag in NoteTagModel.objects.all():
for note in tag.nodemodel_set.all():
print(note.note_title)
…
(I put the html classes in double quotes)
<div >
{% for note in notes %}
<div >
<div >
{{ note.note_title }}
</div>
<!-- loop over all the tags related to the note -->
{% for tag in note.tags.all %}
<div class=”tag_title”>
{{ tag.tag_title }}
</div>
<ul >
<!-- commentary in commentary shouldnt be named the same -->
{% for comment in commentary %}
{% if note_tag == comment.tag_title %}
{% if note == comment.note %}
<li>{{ comment.tag_commentary }}</li>
{% endif %}
{% endif %}
{% endfor %}
</ul>
{% endfor %}
</div>
{% endfor %}
</div>