我打算使用Django为工作时间跟踪编写一个基本的时钟输入/输出应用程序。现在我的代码工作(开始/停止转换或暂停),但我不使用任何ModelForms或ModelManagers。所有业务代码都在我的视图和services.py文件中,这似乎不是正确的方法。
我试着阅读ModelManagers和ModelForms,但我认为这让我很困惑。
假设我有一个模型WorkTime:
class WorkTime(models.Model):
employee = models.ForeignKey(User)
created_at = models.DateTimeField(auto_now_add=True)
shift_started = models.DateTimeField()
shift_finished = models.DateTimeField(blank=True, null=True)
shift_duration = models.DurationField(blank=True, null=True)
work_reason = models.TextField(null=True)
我现在想要两种可能性:
正如我的代码现在,它不是一个真正的美丽,绝对不是干。如何以最聪明的方式解决问题,例如定义适合所有可能情况的ONE ModelForm(只需启动新班次,结束正在运行的班次(仅通过访问浏览器中的视图)或使用HTML手动添加整班班次形成)。或者我会将它分成一个ModelManager来执行shift开始/停止部分,还有一个ModelForm用于手动添加shits作为实际的HTML表单?
答案 0 :(得分:3)
只需通过正常的GET请求输入一些URL,即可更改班次开始和停止时间,这不是一个好主意。浏览器可以缓存这些请求或触发多个请求(刷新页面时没有弹出窗口它可以执行两次操作,比如POST请求)。因此,您最好将其更改为POST请求。
对于所有这些观点,您当然可以使用一个ModelForm
:
class SiftForm(forms.ModelForm):
class Meta:
model = WorkTime
fields = ('created_at', 'shift_started', 'shift_finished') # you shouldn't pass user and duration time here
class ShiftStartView(CreateView):
model = WorkTime
form_class = ShiftForm
success_url = "some_url" # after creating WorkTime, view will redirect to that url. You can (and really should) pass reverse_lazy() here, instead of URL as string, if you don't want to hardcode URL.
def dispatch(self, request, *args, **kwargs):
# if you want to prevent creating 2 started but not stopped WorkTimes for one user, you should put logic preventing it here.
return super(ShiftStartView, self).dispatch(self, request, *args, **kwargs)
def form_valid(self, form):
worktime = form.save(commit=False)
worktime.employee = self.request.user
worktime.save()
return super(ShiftStartView, self).form_valid(form)
通过这种方式,您还可以创建用于手动创建WorkTime
的表单。要创建停止视图,您应该使用UpdateView
并在WorkTime
方法中为用户获取当前get_object
。