Source

gnocchi-ask / gnocchi / ask / views.py

The default branch has multiple heads

Full commit
from django.views import generic
from django.views.generic.edit import SingleObjectMixin
from django.contrib.auth.decorators import permission_required
from django.http import HttpResponseRedirect
from django.contrib import messages
from django.shortcuts import get_object_or_404
import shlex
from django.db.models import Q
from gnocchi.ask import settings, models, forms

__all__ = [
    'QuestionList', 'QuestionDetail', 'QuestionAsk', 'QuestionRespond',
    'question_vote', 'response_accept',
]
class QuestionList(generic.ListView):
    model = models.Question
    paginate_by = settings.QUESTION_PAGE

    def get_queryset(self):
        qset = super(QuestionList, self).get_queryset()
        search = self.request.GET.get('q', '').encode('utf8')
        for term in shlex.split(search.encode('utf8')):
            qset = qset.filter(
                Q(question__icontains=term) |
                Q(content__icontains=term) |
                Q(responses__content__icontains=term)
            )
        return qset

class QuestionDetail(generic.DetailView):
    queryset = models.Question.objects.filter(visible=True)
    def get_context_data(self, **kwargs):
        data = super(QuestionDetail, self).get_context_data(**kwargs)
        data.update({
            'form': forms.AddResponseForm(),
        })
        return data

class QuestionAsk(generic.CreateView):
    model = models.Question
    form_class = forms.AskQuestionForm
    def form_valid(self, form):
        obj = form.save(commit=False)
        obj.user = self.request.user
        obj.save()
        form.save_m2m()
        return HttpResponseRedirect(obj.get_absolute_url())

class QuestionRespond(generic.CreateView):
    form_class = forms.AddResponseForm
    model = models.Question	# So that get_object looks for the right thing
    template_name = 'ask/response_form.html'

    def form_valid(self, form):
        obj = form.save(commit=False)
        obj.user = self.request.user
        obj.question = self.get_object()
        obj.save()
        return HttpResponseRedirect(obj.question.get_absolute_url())

    def get_context_data(self, **kwargs):
        data = super(QuestionRespond, self).get_context_data(**kwargs)
        data.update({
            'question': self.object,
        })
        return data


DIRECTION_WEIGHT = {
    'up': 1,
    'down': -1,
}

@permission_required('response.can_vote')
def question_vote(request, pk, response_id, direction, weight=1):
    response = get_object_or_404(models.Response, pk=pk,
        question__id=question_id)

    weight = DIRECTION_WEIGHT[direction] * weight

    vote, created = models.Vote.objects.get_or_create(user=request.user,
        response=response,
        defaults={'weight': weight}
    )

    if not created:
        if vote.weight == weight:
            # Voted the same
            pass
        elif abs(vote.weight) == abs(weight):
            # Voted opposite
            vote.delete()
        else:
            vote.weight = weight
            vote.save()

    return HttpResponseRedirect(response.question.get_absolute_url())

def response_accept(request, pk, response_id):
    response = get_object_or_404(models.Response, pk=pk, question__id=pk)

    if response.question.user == request.user:
        response.question.accepted = response
        response.question.save()
    else:
        messages.add_message(request, messages.WARNING,
            "You may not accept a response for a question you didn't ask."
        )
    return HttpResponseRedirect(response.question.get_absolute_url())