Example #1
0
def create(request, day_pk):
    """
    Creates a new set. This view handles both the set form and the corresponding
    settings formsets
    """
    day = get_object_or_404(Day, pk=day_pk)
    if day.get_owner_object().user != request.user:
        return HttpResponseForbidden()

    context = {}
    formsets = []
    form = SetForm(initial={'sets': Set.DEFAULT_SETS})

    # If the form and all formsets validate, save them
    if request.method == "POST":
        form = SetForm(request.POST)
        if form.is_valid():
            for exercise in form.cleaned_data['exercises']:
                formset = SettingFormset(request.POST,
                                         queryset=Setting.objects.none(),
                                         prefix='exercise{0}'.format(
                                             exercise.id))
                formsets.append({'exercise': exercise, 'formset': formset})
        all_valid = True

        for formset in formsets:
            if not formset['formset'].is_valid():
                all_valid = False

        if form.is_valid() and all_valid:
            # Manually take care of the order, TODO: better move this to the model
            max_order = day.set_set.select_related().aggregate(
                models.Max('order'))
            form.instance.order = (max_order['order__max'] or 0) + 1
            form.instance.exerciseday = day
            set_obj = form.save()

            order = 1
            for formset in formsets:
                instances = formset['formset'].save(commit=False)
                for instance in instances:
                    instance.set = set_obj
                    instance.order = order
                    instance.exercise = formset['exercise']
                    instance.save()
                    order += 1

            return HttpResponseRedirect(
                reverse('manager:workout:view',
                        kwargs={'pk': day.get_owner_object().id}))
        else:
            logger.debug(form.errors)

    # Other context we need
    context['form'] = form
    context['day'] = day
    context['max_sets'] = Set.MAX_SETS
    context['formsets'] = formsets
    context['helper'] = WorkoutLogFormHelper()
    return render(request, 'set/add.html', context)
Example #2
0
def edit(request, pk):
    """
    Edit a set (its settings actually)
    """
    set_obj = get_object_or_404(Set, pk=pk)
    if set_obj.get_owner_object().user != request.user:
        return HttpResponseForbidden()

    formsets = []
    for exercise in set_obj.exercises:
        queryset = Setting.objects.filter(set=set_obj, exercise=exercise)
        formset = SettingFormset(queryset=queryset,
                                 prefix='exercise{0}'.format(exercise.id))
        formsets.append({'exercise': exercise, 'formset': formset})

    if request.method == "POST":
        formsets = []
        for exercise in set_obj.exercises:
            formset = SettingFormset(request.POST,
                                     prefix='exercise{0}'.format(exercise.id))
            formsets.append({'exercise': exercise, 'formset': formset})

        # If all formsets validate, save them
        all_valid = True
        for formset in formsets:
            if not formset['formset'].is_valid():
                all_valid = False

        if all_valid:
            for formset in formsets:
                instances = formset['formset'].save(commit=False)
                for instance in instances:
                    # If the setting has already a set, we are editing...
                    try:
                        instance.set

                        # Check that we are allowed to do this
                        if instance.get_owner_object().user != request.user:
                            return HttpResponseForbidden()

                        instance.save()

                    # ...if not, create a new setting
                    except ObjectDoesNotExist:
                        instance.set = set_obj
                        instance.order = 1
                        instance.exercise = formset['exercise']
                        instance.save()

            return HttpResponseRedirect(
                reverse('manager:workout:view',
                        kwargs={'pk': set_obj.get_owner_object().id}))

    # Other context we need
    context = {}
    context['formsets'] = formsets
    context['helper'] = WorkoutLogFormHelper()
    return render(request, 'set/edit.html', context)
Example #3
0
def edit(request, pk):
    """
    Edit a set (its settings actually)
    """
    set_obj = get_object_or_404(Set, pk=pk)
    if set_obj.get_owner_object().user != request.user:
        return HttpResponseForbidden()

    SettingFormsetEdit = modelformset_factory(Setting,
                                              form=SettingForm,
                                              fields=SETTING_FORMSET_FIELDS +
                                              ('id', ),
                                              can_delete=False,
                                              can_order=True,
                                              extra=0)

    formsets = []
    for exercise in set_obj.exercises:
        queryset = Setting.objects.filter(set=set_obj, exercise=exercise)
        formset = SettingFormsetEdit(queryset=queryset,
                                     prefix='exercise{0}'.format(exercise.id))
        formsets.append({'exercise': exercise, 'formset': formset})

    if request.method == "POST":
        formsets = []
        for exercise in set_obj.exercises:
            formset = SettingFormsetEdit(request.POST,
                                         prefix='exercise{0}'.format(
                                             exercise.id))
            formsets.append({'exercise': exercise, 'formset': formset})

        # If all formsets validate, save them
        all_valid = True
        for formset in formsets:
            if not formset['formset'].is_valid():
                all_valid = False

        if all_valid:
            for formset in formsets:
                instances = formset['formset'].save(commit=False)

                for instance in instances:
                    # Double check that we are allowed to edit the set
                    if instance.get_owner_object().user != request.user:
                        return HttpResponseForbidden()
                    instance.save()

            return HttpResponseRedirect(
                reverse('manager:workout:view',
                        kwargs={'pk': set_obj.get_owner_object().id}))

    # Other context we need
    context = {'formsets': formsets, 'helper': WorkoutLogFormHelper()}
    return render(request, 'set/edit.html', context)
Example #4
0
def get_formset(request, exercise_pk, reps=Set.DEFAULT_SETS):
    """
    Returns a formset. This is then rendered inside the new set template
    """
    exercise = Exercise.objects.get(pk=exercise_pk)
    SettingFormSet = inlineformset_factory(Set,
                                           Setting,
                                           can_delete=False,
                                           extra=int(reps),
                                           fields=SETTING_FORMSET_FIELDS)
    formset = SettingFormSet(queryset=Setting.objects.none(),
                             prefix='exercise{0}'.format(exercise_pk))
    context = {
        'formset': formset,
        'helper': WorkoutLogFormHelper(),
        'exercise': exercise
    }

    return render(request, "set/formset.html", context)
Example #5
0
def add(request, pk):
    """
    Add a new workout log
    """

    # NOTE: This function is waaaay too complex and convoluted. While updating
    #       to crispy forms, the template logic could be reduced a lot, but
    #       there is still a lot optimisations that could happen here.

    # Load the day and check ownership
    day = get_object_or_404(Day, pk=pk)
    if day.get_owner_object().user != request.user:
        return HttpResponseForbidden()

    # We need several lists here because we need to assign specific form to each
    # exercise: the entries for weight and repetitions have no indicator to which
    # exercise they belong besides the form-ID, from Django's formset
    counter = 0
    total_sets = 0
    exercise_list = {}
    form_to_exercise = {}

    for exercise_set in day.set_set.all():
        for exercise in exercise_set.exercises.all():

            # Maximum possible values
            total_sets += int(exercise_set.sets)
            counter_before = counter
            counter = counter + int(exercise_set.sets) - 1
            form_id_range = range(counter_before, counter + 1)

            # Add to list
            exercise_list[exercise.id] = {
                'obj': exercise,
                'sets': int(exercise_set.sets),
                'form_ids': form_id_range
            }

            counter += 1
            # Helper mapping form-ID <--> Exercise
            for id in form_id_range:
                form_to_exercise[id] = exercise

    # Define the formset here because now we know the value to pass to 'extra'
    WorkoutLogFormSet = modelformset_factory(WorkoutLog,
                                             form=WorkoutLogForm,
                                             exclude=('date', 'workout'),
                                             extra=total_sets)
    # Process the request
    if request.method == 'POST':

        # Make a copy of the POST data and go through it. The reason for this is
        # that the form expects a value for the exercise which is not present in
        # the form (for space and usability reasons)
        post_copy = request.POST.copy()

        for form_id in form_to_exercise:
            if post_copy.get('form-%s-weight' % form_id) or post_copy.get(
                    'form-%s-reps' % form_id):
                post_copy['form-%s-exercise' %
                          form_id] = form_to_exercise[form_id].id

        # Pass the new data to the forms
        formset = WorkoutLogFormSet(data=post_copy)
        session_form = HelperWorkoutSessionForm(data=post_copy)

        # If all the data is valid, save and redirect to log overview page
        if session_form.is_valid() and formset.is_valid():
            log_date = session_form.cleaned_data['date']

            if WorkoutSession.objects.filter(user=request.user,
                                             date=log_date).exists():
                session = WorkoutSession.objects.get(user=request.user,
                                                     date=log_date)
                session_form = HelperWorkoutSessionForm(data=post_copy,
                                                        instance=session)

            # Save the Workout Session only if there is not already one for this date
            instance = session_form.save(commit=False)
            if not WorkoutSession.objects.filter(user=request.user,
                                                 date=log_date).exists():
                instance.date = log_date
                instance.user = request.user
                instance.workout = day.training
            else:
                session = WorkoutSession.objects.get(user=request.user,
                                                     date=log_date)
                instance.instance = session
            instance.save()

            # Log entries (only the ones with actual content)
            instances = [i for i in formset.save(commit=False) if i.reps]
            for instance in instances:
                if not instance.weight:
                    instance.weight = 0
                instance.user = request.user
                instance.workout = day.training
                instance.date = log_date
                instance.save()

            return HttpResponseRedirect(
                reverse('manager:log:log', kwargs={'pk': day.training_id}))
    else:
        # Initialise the formset with a queryset that won't return any objects
        # (we only add new logs here and that seems to be the fastest way)
        user_weight_unit = 1 if request.user.userprofile.use_metric else 2
        formset = WorkoutLogFormSet(queryset=WorkoutLog.objects.none(),
                                    initial=[{
                                        'weight_unit': user_weight_unit,
                                        'repetition_unit': 1
                                    } for x in range(0, total_sets)])

        # Depending on whether there is already a workout session for today, update
        # the current one or create a new one (this will be the most usual case)
        if WorkoutSession.objects.filter(user=request.user,
                                         date=datetime.date.today()).exists():
            session = WorkoutSession.objects.get(user=request.user,
                                                 date=datetime.date.today())
            session_form = HelperWorkoutSessionForm(instance=session)
        else:
            session_form = HelperWorkoutSessionForm()

    # Pass the correct forms to the exercise list
    for exercise in exercise_list:

        form_id_from = min(exercise_list[exercise]['form_ids'])
        form_id_to = max(exercise_list[exercise]['form_ids'])
        exercise_list[exercise]['forms'] = formset[form_id_from:form_id_to + 1]

    context = {}
    context['day'] = day
    context['exercises'] = exercise_list
    context['formset'] = formset
    context['helper'] = WorkoutLogFormHelper()
    context['session_form'] = session_form
    context['form'] = session_form
    context['extend_template'] = 'base.html'
    context['form_action'] = request.path

    return render(request, 'log/add.html', context)