in app, have 3 models: issue, series, , character. issue model has series foreignkey, , character manytomanyfield. here simplified:
class character(models.model): name = models.charfield('character name', max_length=200) desc = models.textfield('description', max_length=500) class series(models.model): name = models.charfield('series name', max_length=200) desc = models.textfield('description', max_length=500) class issue(models.model): series = models.foreignkey(series, on_delete=models.cascade, blank=true) name = models.charfield('issue name', max_length=200) number = models.positivesmallintegerfield('issue number') date = models.datefield('cover date') desc = models.textfield('description', max_length=500) characters = models.manytomanyfield(character, blank=true) cover = models.filepathfield('cover file path', path="media/images/covers")
i have character template displays information character. want display issues character in, sorted series.
{% extends "app/base.html" %} {% block page-title %}{{ character.name }}{% endblock page-title %} {% block content %} <div class="description"> <p>{{ character.desc }}</p> </div> <div class="issues"> <h3>issues</h3> {% series in character.issue_set.all %} <div> <a href="{% url 'app:series' series.id %}">{{ series.name }}</a> <ul> {% issue in character.issue_set.all %} {% if issue.series.name == series.name %} <li> <a href="{% url 'app:issue' issue.id %}"><img src="/{{ issue.cover }}" alt = "{{ series.name }}" ></a> <a href="{% url 'app:issue' issue.id %}"><p>issue #{{ issue.number }}</p></a> </li> {% endif %} {% endfor %} </ul> </div> {% endfor %} </div> {% endblock content %}
obviously, way formats every issue in set, outputs series title, , each issue in set.
<div class="issues"> <h3>issues</h3> <div> <a href="/series/1">series 1</a> <ul> <li> <a href="/issue/1"><img src="/media/images/covers/01.jpg" alt="series 1"></a> <a href="/issue/1"><p>issue #1</p></a> </li> <li> <a href="/issue/2"><img src="/media/images/covers/02.jpg" alt="series 1"></a> <a href="/issue/2"><p>issue #2</p></a> </li> </ul> </div> <div> <a href="/series/1">series 1</a> <ul> <li> <a href="/issue/1"><img src="/media/images/covers/01.jpg" alt="series 1"></a> <a href="/issue/1"><p>issue #1</p></a> </li> <li> <a href="/issue/2"><img src="/media/images/covers/02.jpg" alt="series 1"></a> <a href="/issue/2"><p>issue #2</p></a> </li> </ul> </div> </div>
here's see:
<div class="issues"> <h3>issues</h3> <div> <a href="/series/1">series 1</a> <ul> <li> <a href="/issue/1"><img src="/media/images/covers/01.jpg" alt="series 1"></a> <a href="/issue/1"><p>issue #1</p></a> </li> <li> <a href="/issue/2"><img src="/media/images/covers/02.jpg" alt="series 1"></a> <a href="/issue/2"><p>issue #2</p></a> </li> </ul> </div> </div>
i've researched quite bit on templating, , i'm not seeing way listing based on distinct values. i've tried creating new set in character or issue model use replace issue_set.all
, have yet working.
edit: upon request of marcusshep, character view using generic detailview:
class characterview(generic.detailview): model = character template_name = 'app/character.html'
i use function based view rather class based generic view. reason being required behavior going beyond generic.
in function can build queryset desire instead of having fight 1 provided generic.detailview
.
def my_view(request, *args, **kwargs): character = character.objects.get(id=request.get.get("id", none)) issues = character.issue_set.all().order_by("series__name") return render(request, 'app/character.html', {"issues": issues})
alternatively, can use have , override detailview's get_queryset() method.
class characterview(generic.detailview): model = character template_name = 'app/character.html' def get_queryset(): # return correct queryset
the biggest problem though there more aspects need use set. instance, i'll adding creators, story arcs, etc. have own pages , need display related issues, sorted series well. nice have solution can used of these templates without code re-use.
this common problem in areas of programming. simple way solve isolate logic in 1 function , call function whenever need it.
def my_issues_query(): # find objects need def my_view(request, *args, **kwargs): issues = my_issues_query()
you can take advantage of pythons decorator functions. (which favorite approach.)
def has_issues(view_function): def get_issues(request, *args, **kwargs): # find issues need here # you'll need write logic once. issues = issues.objects.filter(...) return issues return get_issues @has_issues def my_view(request, *args, **kwargs): # functions namespace contains # variable `issues`. # allows use of query ie. return render( request, "my_templates/template.html", {"issues":issue} )
Comments
Post a Comment