在表单周围传递额外的上下文

时间:2017-09-10 10:07:38

标签: django

我有两个模型,BoardProblem。每个Board都有许多Problem与之关联。

class Board(models.Model):
    author = models.ForeignKey(User, unique=False, on_delete=models.CASCADE)
    create_date = models.DateField(auto_now=False, auto_now_add=True)

class Problem(models.Model):
    board = models.ForeignKey(Board, unique=False, on_delete=models.CASCADE)
    problem = models.TextField()

然后我有一个页面,我可以在单个Problem实例中更新值。

class ProblemStudyView(UpdateView):
    model = Problem
    fields = "__all__"
    template_name = "board/study.html"

    def get_success_url(self):
        success_url = reverse_lazy('board:problem-study', kwargs={'pk': self.kwargs['pk']})
        return success_url

这是更新Problem的良好形式。但是我想再添加两个网址,"之前的问题"和"下一个问题"。对于共享同一父ProblemStudyView的下一个或上一个问题,这些链接指向同一Board

我的问题是,我不知道在ProblemStudyView课程中我可以生成此上下文以供应给模板。我需要运行两个查询 - "当前问题的主板是什么"和#34;共享这个共同父母委员会的问题清单是什么?"然后我可以指出要考虑的上一个和下一个Problem

这看起来有些令人费解,所以我猜想我仍然缺少一些更聪明的方法来做这件事,同时仍然喜欢使用基于UpdateView的课程。

=========================================== 更新

我重写了get_context_data()方法,但我正在努力弄清楚如何引用原始的Problem,以便我可以生成我需要的上下文。

ProblemStudyView最初传递了Problem来制作表单。但我不知道如何在Problem方法中引用get_context_data。我的最佳猜测是self.Problem.board,但Problem不是ProblemStudyView

的字段
def get_context_data(self, **kwargs):
    context = super(ProblemStudyView, self).get_context_data(**kwargs)
    parent = self.Problem.board
    all_children = Problem.objects.filter(board = parent)
    context['foo'] = F"{len(all_children)} children available"

    return context

============================================== < / p>

熊布朗的修正案:

def get_context_data(self, **kwargs):

    #problem?  I changed the parameters passed to method
    #get_context_data() takes 1 positional argument but 2 were given
    #context = super(ProblemStudyView, self).get_context_data(self, **kwargs)
    context = super(ProblemStudyView, self).get_context_data( **kwargs)

    #But I still have no way to get the Problem
    #ProblemStudyView' object has no attribute 'Problem'
    items = self.Problem.board.problem_set.all().order_by('pk')


    # page number just count problems with less or equaul pk
    page = items.filter(pk__lte=self.Problem.pk).count()
    # initial django paginator with 1 item per page
    paginator = Paginator(items, 1)
    # add pagination to the context
    context['pagination'] = paginator.page(page)
    context['foo']="new version"
    return context

======================

...最终

    #my version
    #the_problem = get_object_or_404(Problem, pk=self.kwargs['pk'])
    #all_problems = the_problem.board.problem_set.all().order_by('pk')

    #bear's version
    all_problems = self.get_object().board.problem_set.all().order_by('pk')

我不知道self.get_object()方法。这就是我所需要的。 Bear可能比我的后门get_object_or_404 hack更健壮/更正确地做到这一点......至少保存数据库访问权限。

1 个答案:

答案 0 :(得分:1)

您可以覆盖get_context_data

from django.core.paginator import Paginator

class ProblemStudyView(UpdateView):

    def get_context_data(self, **kwargs):
        context = super(ProblemStudyView, self).get_context_data(**kwargs)
        # all parent board problems order by pk -- change order if need
        items = self.get_object().board.problem_set.all().order_by('pk')
        # page number just count problems with less or equaul pk
        page = items.filter(pk__lte=self.Problem.pk).count()
        # initial django paginator with 1 item per page
        paginator = Paginator(items, 1)
        # add pagination to the context
        context['pagination'] = paginator.page(page)

        return context