Django 不完全确定我的两个CBV应该如何从一个基地继承

Django 不完全确定我的两个CBV应该如何从一个基地继承,django,django-views,django-templates,Django,Django Views,Django Templates,我已经意识到我有两个CBV,99%的代码相同,所以我想我应该把它抽象出来,并使用一个mixin,在那里我可以放置所有的“通用”代码。视图之间唯一的真正区别是它们渲染的模板。我很难弄清楚什么课应该放什么。这是原来的两辆CBV 1级 @method_decorator(login_required, name='dispatch') class TimesheetEditorView(View): form_class = TimesheetModelFormSet def ge

我已经意识到我有两个CBV,99%的代码相同,所以我想我应该把它抽象出来,并使用一个mixin,在那里我可以放置所有的“通用”代码。视图之间唯一的真正区别是它们渲染的模板。我很难弄清楚什么课应该放什么。这是原来的两辆CBV

1级

@method_decorator(login_required, name='dispatch')
class TimesheetEditorView(View):
    form_class = TimesheetModelFormSet


    def get(self, request, *args, **kwargs):
        year = kwargs.get("year") or datetime.datetime.now().year
        week = kwargs.get("week") or Week.thisweek().week
        user = request.user
        if invalid_week(week, year):
            raise Http404("Invalid week / year")

        next_year, next_week = calc_next(year, week)
        previous_year, previous_week = calc_previous(year, week)


        timesheet = Timesheet.objects.filter(year=year, week=week, user=user).order_by("project_id")  # only show timesheet rows that belongs to logged in user

        timesheet_formset = self.form_class(queryset=timesheet)
        create_timesheet_form = TimesheetModelForm(user)
        context = {
            "create_timesheet_form": create_timesheet_form,
            "timesheet_formset": timesheet_formset,
            "week": week,
            "year": year,
            "next_week": next_week,
            "next_year": next_year,
            "previous_week": previous_week,
            "previous_year": previous_year,
        }

        return render(request, "timesheets/timesheet.html", context)
Class 2

class TimesheetApproveView(TimesheetEditorView, View):

    def get(self, request, *args, **kwargs):
        year = kwargs.get("year") or datetime.datetime.now().year
        week = kwargs.get("week") or Week.thisweek().week
        next_year, next_week = calc_next(year, week)
        previous_year, previous_week = calc_previous(year, week)
        timesheets = Timesheet.objects.timesheets_to_approve(request.user).filter(year=year, week=week)
        context = {
            "timesheets": timesheets, 
            "year": year, 
            "week": week, 
            "next_week": next_week,
            "next_year": next_year,
            "previous_week": previous_week,
            "previous_year": previous_year,
        }

        return render(request, "timesheets/approve_timesheets.html", context)
我只是简单地将TimesheetEditorView继承到我的第二个类中。 如您所见,这里唯一的区别是
return
语句中呈现的模板

所以,我想我应该把这段代码放在一个基本的mixin中:

class BaseTimesheet(object):

    def get_context_data(self, **kwargs):
        context = super(BaseTimesheet, self).get_context_data(**kwargs)
        year = kwargs.get("year") or datetime.datetime.now().year
        week = kwargs.get("week") or Week.thisweek().week

        next_year, next_week = calc_next(year, week)
        previous_year, previous_week = calc_previous(year, week)

        if invalid_week(week, year):
            raise Http404("Invalid week / year")

        context["week"] = week
        context["year"] = year
        context["next_week"] = next_week
        context["previous_week"] = previous_week
        context["next_year"] = next_year
        context["previous_year"] = previous_year

这是“正确”的方法吗?如果是-如何确保在我的两个
视图
类中为每个
返回
语句获取
上下文

例如

approve\u timesheets.html

{% extends "base_layout.html" %}
{% load crispy_forms_tags %}
{% load static %}
{% block content %}




<section class="mb-3">
    <div class="col-lg-8 offset-lg-2">
        <div class="d-flex">


            <h5>Timesheet approvals</h5>
            <div class="ml-auto py-2">
                <a uk-icon="icon: chevron-left; ratio: 1.2"
                    href="{% url 'timesheets:approve-week' previous_year previous_week %}" role="button">
                </a>
                <a class="uk-button uk-button-default uk-button-small"
                    href="{% url 'timesheets:default-approve-week' %}" role="button">
                    <span>Current week</span>
                </a>

                <a uk-icon="icon: chevron-right; ratio: 1.2"
                    href="{% url 'timesheets:approve-week' next_year next_week %}" role="button">
                </a>

            </div>

        </div>
    </div>
</section>



{% regroup timesheets by project as projects %}
<div class="row">
    <div class="col-xl-8 offset-xl-2 col-lg-10 offset-lg-1 ">
        <form method="post" autocomplete="off">
            <div class="table-responsive-sm">
                {% for project in projects %}
                <table class="table approve-timesheet-table">
                    <thead class="thead-light">
                        <tr>
                            <th>{{project.grouper}}</th>
                            <th>Mon</th>
                            <th>Tue</th>
                            <th>Wed</th>
                            <th>Thu</th>
                            <th>Fri</th>
                            <th>Sat</th>
                            <th>Sun</th>
                            <th></th>
                            <th></th>

                        </tr>
                    </thead>

                    <tbody>
                        {% for user in project.list %}
                          ...
                        {% endfor %}
                    </tbody>
                </table>
                {% empty %}
                <p>No timesheets to approve for this week</p>
                <hr>
                {% endfor %}
            </div>



        </form>
    </div>
</div>






{% endblock %}
{%extensed“base_layout.html”%}
{%load crispy_forms_tags%}
{%load static%}
{%block content%}
时间表批准
{%按项目将时间表重新分组为项目%}
{项目%中的项目为%}
{{project.grouper}}
周一
星期二
结婚
清华大学
星期五
坐
太阳
{project.list%中的用户为%1}
...
{%endfor%}
{%empty%}
本周没有可批准的时间表


{%endfor%} {%endblock%}
首先,您忘了返回
上下文:

class BaseTimesheet:

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        year = kwargs.get("year") or datetime.datetime.now().year
        week = kwargs.get("week") or Week.thisweek().week

        next_year, next_week = calc_next(year, week)
        previous_year, previous_week = calc_previous(year, week)

        if invalid_week(week, year):
            raise Http404("Invalid week / year")

        context["week"] = week
        context["year"] = year
        context["next_week"] = next_week
        context["previous_week"] = previous_week
        context["next_year"] = next_year
        context["previous_year"] = previous_year
        return context
在另一个视图中,您可以为表单添加逻辑:

from django.contrib.auth.mixins import LoginRequiredMixin

class TimesheetEditorView(LoginRequiredMixin, BaseTimesheet, TemplateView):
    form_class = TimesheetModelFormSet
    template_name = "timesheets/timesheet.html"

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        timesheet = Timesheet.objects.filter(
            year=context['year'],
            week=context['week'],
            user=self.request.user
        ).order_by("project_id")
        timesheet_formset = self.form_class(queryset=timesheet)
        create_timesheet_form = TimesheetModelForm(user)
        context.update(
            create_timesheet_form=create_timesheet_form,
            timesheet_formset=timesheet_formset
        )
        return context
注意:您可以将基于类的视图限制为具有


我只是在使用TemplateView
Reverse for“approve week”时遇到url模式错误,未找到参数“(”)”。尝试了1个模式:[“时间表/批准/(?P[0-9]+)/(?P[0-9]+)/$”]
(因为我的URL@erikvm:不,这表示您使用了
{%url…%}
,但
不在呈现此内容的上下文中。@erikvm:您可以编辑问题并添加模板的相关部分吗?已更新。未添加
,因为我假设它将由具有
上下文[“周”]=week
上下文[“年”]=year
@erikvm的基本对象处理。erikvm:通常是的,但您忘记在mixin中返回
上下文
class TimesheetApproveView(BaseTimesheet, View):
    template_name = "timesheets/approve_timesheets.html"

    def get(self, request, *args, **kwargs):
        return render(request, "timesheets/timesheet.html", self.get_context_data(**kwargs))
from django.views.generic.base import TemplateView

class TimesheetApproveView(BaseTimesheet, TemplateView):
    template_name = "timesheets/approve_timesheets.html"
from django.contrib.auth.mixins import LoginRequiredMixin

class TimesheetEditorView(LoginRequiredMixin, BaseTimesheet, TemplateView):
    form_class = TimesheetModelFormSet
    template_name = "timesheets/timesheet.html"

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        timesheet = Timesheet.objects.filter(
            year=context['year'],
            week=context['week'],
            user=self.request.user
        ).order_by("project_id")
        timesheet_formset = self.form_class(queryset=timesheet)
        create_timesheet_form = TimesheetModelForm(user)
        context.update(
            create_timesheet_form=create_timesheet_form,
            timesheet_formset=timesheet_formset
        )
        return context