Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用不同外键进行循环迭代的Django模板_Python_Django_For Loop_Django Templates - Fatal编程技术网

Python 使用不同外键进行循环迭代的Django模板

Python 使用不同外键进行循环迭代的Django模板,python,django,for-loop,django-templates,Python,Django,For Loop,Django Templates,在我的应用程序中,我有3个模型:问题、系列和角色。问题模型有一系列外键和一个字符ManyToManyField。此处对其进行了简化: class Character(models.Model): name = models.CharField('Character name', max_length=200) desc = models.TextField('Description', max_length=500) class Series(models.Model):

在我的应用程序中,我有3个模型:问题、系列和角色。问题模型有一系列外键和一个字符ManyToManyField。此处对其进行了简化:

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")
我有一个显示角色信息的角色模板。我还想显示角色所处的问题,按序列排序

{% 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>
    {% for series in character.issue_set.all %}
    <div>
        <a href="{% url 'app:series' series.id %}">{{ series.name }}</a>
        <ul>
        {% for 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 %}

我会使用基于函数的视图,而不是基于类的泛型视图。原因是您所需的行为超出了一般行为

在函数中,您可以构建所需的查询集,而不必与
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})
或者,您可以使用已有的内容并覆盖


但最大的问题是,将有更多方面需要使用此集合。例如,我将添加创建者、故事弧等。它们将有自己的页面,并且需要显示相关问题,并按系列进行排序。如果有一个解决方案可以由这些模板中的任何一个使用,而无需大量代码重用,那就太好了

这在编程的所有领域都是一个非常常见的问题。解决这个问题的一个非常简单的方法是将逻辑隔离在一个函数中,并在需要时调用该函数

def my_issues_query():
    # find the objects you need

def my_view(request, *args, **kwargs):
    issues = my_issues_query()
您还可以利用pythons的decorator函数。(这是我最喜欢的方法。)


我可以看到您将
字符
查询集传递给模板的视图吗?@marcusshep,已使用视图代码进行更新。因此,为了清楚起见,您希望模板仅显示具有不同名称的字符,请更正?@marcusshep很抱歉,我想显示字符所处的问题,按系列排序。但最大的问题是,将有更多方面需要使用此集合。例如,我将添加创建者、故事弧等。它们将有自己的页面,并且需要显示相关问题,并按系列进行排序。如果有一个解决方案可以被这些模板中的任何一个使用,而不需要太多的代码重用,那就太好了。是的,只需编写一个函数,并在需要的地方调用它。请参阅更新的答案。这不只是将
问题
对象的结果传递给模板,而不传递
字符
对象吗?也许我的脑袋还不太清楚,但在我看来,你应该把
字符
作为模板的主要对象,然后通过
字符
过滤,将
问题
对象拉进来。我对Django很陌生,所以我诚实地问!谢谢你迄今为止的帮助!您的查询可以是您需要的任何内容。这一部分取决于你和摆弄。您可以在一个函数中定义两个或多个查询并返回所有查询:
返回问题、字符、我需要的任何其他内容
我不知道您可以返回多个对象!所以我可以这样做?:
返回render(请求,“app/template.html”,“character”:character,“issues”:issues}
class CharacterView(generic.DetailView):
    model = Character
    template_name = 'app/character.html'
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})
class CharacterView(generic.DetailView):
    model = Character
    template_name = 'app/character.html'

    def get_queryset():
        # return correct queryset
def my_issues_query():
    # find the objects you need

def my_view(request, *args, **kwargs):
    issues = my_issues_query()
def has_issues(view_function):
    def get_issues(request, *args, **kwargs):
        # find all the issues you need here
        # you'll only need to write this logic once.
        issues = Issues.objects.filter(...)
        return issues
    return get_issues

@has_issues
def my_view(request, *args, **kwargs):
    # this functions namespace now contains
    # the variable `issues`.
    # which allows for the use of the query ie.
    return render(
        request, 
        "my_templates/template.html", 
        {"issues":issue}
    )