Django 不完全确定我的两个CBV应该如何从一个基地继承
我已经意识到我有两个CBV,99%的代码相同,所以我想我应该把它抽象出来,并使用一个mixin,在那里我可以放置所有的“通用”代码。视图之间唯一的真正区别是它们渲染的模板。我很难弄清楚什么课应该放什么。这是原来的两辆CBVDjango 不完全确定我的两个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
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
注意:您可以将基于类的视图限制为具有
我只是在使用TemplateViewReverse 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