<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def preferences_view(request, semester, targetUsername, profile=None):
 """ Show the user their preferences for the given semester. """

    # TODO: Change template to show descriptions in tooltip / ajax show box?
    wprofile = get_object_or_404(
        WorkshiftProfile,
        user__username=targetUsername,
    )
    full_management = utils.can_manage(request.user, semester=semester)

    if wprofile.user != request.user and \
       not full_management:
        messages.add_message(
            request,
            messages.ERROR,
            MESSAGES["ADMINS_ONLY"],
        )
        return HttpResponseRedirect(semester.get_view_url())

    rating_forms = []
    for wtype in WorkshiftType.objects.filter(rateable=True):
        try:
            rating = wprofile.ratings.get(workshift_type=wtype)
        except WorkshiftRating.DoesNotExist:
            rating = WorkshiftRating(workshift_type=wtype)
        form = WorkshiftRatingForm(
            data=request.POST or None,
            prefix="rating-{}".format(wtype.pk),
            instance=rating,
            profile=wprofile,
        )
        rating_forms.append(form)

    time_formset = TimeBlockFormSet(
        data=request.POST or None,
        prefix="time",
        profile=wprofile,
    )
    note_form = ProfileNoteForm(
        data=request.POST or None,
        instance=wprofile,
        prefix="note",
    )

    if all(i.is_valid() for i in rating_forms) and time_formset.is_valid() and \
       note_form.is_valid():
        for form in rating_forms:
            form.save()
        time_formset.save()
        note_form.save()
        if wprofile.preference_save_time is None:
            wprofile.preference_save_time = now()
            wprofile.save()
        messages.add_message(
            request,
            messages.INFO,
            "Preferences saved.",
        )
        return HttpResponseRedirect(wurl(
            "workshift:preferences",
            sem_url=semester.sem_url,
            targetUsername=request.user.username,
        ))

    if wprofile == profile:
        page_name = "My Workshift Preferences"
    else:
        page_name = "{}'s Workshift Preferences".format(
            wprofile.user.get_full_name(),
        )
    return render_to_response("preferences.html", {
        "page_name": page_name,
        "profile": wprofile,
        "rating_forms": rating_forms,
        "time_formset": time_formset,
        "note_form": note_form,
    }, context_instance=RequestContext(request))