gnocchi-ask / gnocchi / ask / views.py

The default branch has multiple heads

from django.views import generic
from django.views.generic.edit import SingleObjectMixin
from django.core.exceptions import ObjectDoesNotExist
from django.http import HttpResponseRedirect, Http404
from django.contrib import messages
import shlex
from django.db.models import Q
from gnocchi.ask import settings, models, forms

__all__ = [
    'QuestionList', 'QuestionDetail', 'QuestionAsk', 'QuestionRespond',
    'ResponseVote', 'ResponseAccept',
]
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 ResponseMixin(SingleObjectMixin):
    '''Operate on Responses of questions, where pk is the Question,
    and response_id is the Response'''
    model = models.Question
    def get_object(self, queryset=None):
        self.question = super(ResponseMixin, self).get_object(queryset)
        try:
            obj = self.question.responses.get(pk=self.kwargs['response_id'])
        except ObjectDoesNotExist:
            raise Http404
        return obj

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,
}

class ResponseVote(ResponseMixin, generic.View):
    def get(self, request, direction, weight=1, *args, **kwargs):
        self.object = self.get_object()
        weight = DIRECTION_WEIGHT[direction] * weight

        vote, created = models.Vote.objects.get_or_create(user=request.user,
            response=self.object,
            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(self.question.get_absolute_url())

class ResponseAccept(ResponseMixin, generic.View):
    '''Mark a response as the Accepted correct one.'''
    def get(self, request, *args, **kwargs):
        self.object = self.get_object()

        if self.object.question.user == request.user:
            self.object.question.accepted = self.object
            self.object.question.save()
        else:
            messages.add_message(request, messages.WARNING,
                "You may not accept a response for a question you didn't ask."
            )
        return HttpResponseRedirect(self.object.question.get_absolute_url())
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.