Django Managers,ModelForms和一些混乱

时间:2015-09-04 13:52:18

标签: django django-forms dry business-logic django-managers

我打算使用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)

我现在想要两种可能性:

  • 用户可以通过访问特定的视图(/ clock / start /)来开始他的班次。只添加了开始时间。
  • 用户访问停止视图(/ clock / stop /)以结束当前的班次,将完成时间添加到相应的行中。
  • 用户在完成后手动添加他的班次,因此添加了开始和结束时间。

正如我的代码现在,它不是一个真正的美丽,绝对不是干。如何以最聪明的方式解决问题,例如定义适合所有可能情况的ONE ModelForm(只需启动新班次,结束正在运行的班次(仅通过访问浏览器中的视图)或使用HTML手动添加整班班次形成)。或者我会将它分成一个ModelManager来执行shift开始/停止部分,还有一个ModelForm用于手动添加shits作为实际的HTML表单?

1 个答案:

答案 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