2015-09-04 5 views
0

Я планировал написать базовое приложение часов-часов/часов для отслеживания рабочего времени с использованием Django. Сейчас мой код работает (запуск/остановка сдвига или пауза), но я не использую ModelForms или ModelManager. Весь бизнес-код находится внутри моих представлений и файла services.py, это не похоже на правильный путь.Менеджеры Django, ModelForms и некоторая путаница

Я попытался прочитать в ModelManager и 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/stop /), чтобы завершить его текущий сдвиг, время окончания добавлено в соответствующую строку.
  • Пользователь добавляет свою смену вручную после ее завершения, поэтому добавляет время начала и окончания.

Как мой код прямо сейчас, это не настоящая красота и определенно не сухая. Как я могу решить проблему наиболее умным способом, например, определить ONE ModelForm, который подходит для всех возможных случаев (просто запустите новый сдвиг, завершите смену (только путем доступа к представлениям в браузере) или добавьте всю смену вручную с помощью HTML- форма). Или я бы разделил его на то, чтобы иметь ModelManager, который делает стартовую/остальную часть сдвига и ModelForm для ручного добавления shits в качестве фактической HTML-формы?

ответ

3

Изменение начального и стартового времени смены просто путем ввода некоторого URL-адреса через обычный запрос GET - это не очень хорошая идея. Браузеры могут кэшировать запросы или огонь, запрашивающие более одного (во время обновления страницы не появляется всплывающее окно, которое может выполнять операцию дважды, например, на 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.

+0

спасибо! Еще один вопрос: почему я должен добавить 'created_at' в поля, так как это опция auto_now_add = True в модели. Разве это не было бы лишним? –

+0

Прости, плохо. Этого не должно быть здесь. – GwynBleidD

+0

Я еще не двигался дальше. Для моего приложения я хочу, чтобы у пользователя было два способа начать его смену. a) Нажмите кнопку, которая теперь отправляет форму и начинает смену b) Заполните форму вручную со всеми данными (время начала и окончания) Я думал, что могу использовать тот же CreateView/ModelForm для этого , но я не могу преодолеть процесс проверки. Если пользователь просто нажимает кнопку, тогда обычно время начала не отправляется (поскольку его не указывается, пользователь просто нажимает кнопку!). Теперь я хотел бы добавить start_time вручную в представление, но я думаю, что я потерялся. –