dirtycoder/pets

View on GitHub
pets/meupet/views.py

Summary

Maintainability
A
0 mins
Test Coverage
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.db import IntegrityError, transaction
from django.db.models import Q
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.utils.translation import ugettext as _
from django.views.decorators.http import require_POST
from django.views.generic import CreateView, FormView, ListView, UpdateView

from meupet import forms, models
from meupet.forms import SearchForm
from meupet.models import StatusGroup


class PetIndexView(ListView):
    template_name = "meupet/index.html"
    context_object_name = "pets"

    def get_queryset(self):
        return models.Pet.objects.select_related("city").order_by("-id")[:12]


def pet_detail_view(request, pk_or_slug):
    pet = models.Pet.objects.filter(slug=pk_or_slug).first()

    if not pet:
        try:
            pet = models.Pet.objects.get(pk=pk_or_slug)
        except ValueError:
            raise Http404()

    context = {"pet": pet, "pet_url": request.build_absolute_uri(reverse("meupet:detail", args=[pet.slug]))}
    return render(request, "meupet/pet_detail.html", context)


def paginate_pets(queryset, page, paginate_by=12):
    """Returns the pets for the current requested page and the page number"""
    paginator = Paginator(queryset, paginate_by)

    try:
        pets = paginator.page(page)
        page = int(page)
    except PageNotAnInteger:
        pets = paginator.page(1)
        page = 1
    except EmptyPage:
        pets = paginator.page(paginator.num_pages)
        page = paginator.num_pages

    return pets, page


def render_pet_list(request, kind, status, queryset):
    pets, page = paginate_pets(queryset, request.GET.get("page"))

    return render(
        request, "meupet/pet_list.html", {"pets": pets, "kind": kind, "status": status, "current_page": page}
    )


def pet_list(request, group, kind):
    group = get_object_or_404(StatusGroup, slug=group)
    queryset = models.Pet.objects.select_related("city")
    queryset = queryset.filter(active=True)
    queryset = queryset.filter(status__in=group.statuses.all(), kind__slug=kind)

    pets, page = paginate_pets(queryset, request.GET.get("page"))

    return render(
        request,
        "meupet/pet_list.html",
        {"pets": pets, "kind": kind, "status": group.name, "current_page": page},
    )


class RegisterPetView(LoginRequiredMixin, CreateView):
    template_name = "meupet/register_pet.html"
    model = models.Pet
    form_class = forms.PetForm

    def get_success_url(self):
        return reverse("meupet:registered", args=[self.object.slug])

    def get(self, request, *args, **kwargs):
        if not request.user.is_information_confirmed:
            messages.warning(request, _("Please confirm your informations before registering a new pet."))
            return HttpResponseRedirect(reverse("users:edit"))
        else:
            return super(RegisterPetView, self).get(request, *args, **kwargs)

    @transaction.atomic()
    def post(self, request, *args, **kwargs):
        try:
            return super().post(request, *args, **kwargs)
        except IntegrityError:
            messages.info(request, _("You already have a pet registered with this name."))
            return HttpResponseRedirect(reverse("users:profile"))

    def form_valid(self, form):
        form.instance.owner = self.request.user
        return super(RegisterPetView, self).form_valid(form)


class EditPetView(UpdateView):
    template_name = "meupet/edit.html"
    form_class = forms.PetForm
    model = models.Pet

    def get(self, request, *args, **kwargs):
        current_pet = self.get_object()
        if request.user == current_pet.owner:
            return super(EditPetView, self).get(request, *args, **kwargs)
        else:
            return HttpResponseRedirect(reverse("meupet:detail", kwargs={"pk_or_slug": current_pet.slug}))

    def form_valid(self, form):
        return super(EditPetView, self).form_valid(form)


@require_POST
def delete_pet(request, slug):
    pet = get_object_or_404(models.Pet, slug=slug)

    if request.user == pet.owner:
        pet.delete()
        return HttpResponseRedirect(reverse("meupet:index"))

    return HttpResponseRedirect(pet.get_absolute_url())


@require_POST
def change_status(request, slug):
    pet = get_object_or_404(models.Pet, slug=slug)

    if request.user != pet.owner:
        return HttpResponseRedirect(pet.get_absolute_url())

    pet.change_status()
    return HttpResponseRedirect(reverse("meupet:detail", kwargs={"pk_or_slug": pet.slug}))


def upload_image(request, slug):
    pet = get_object_or_404(models.Pet, slug=slug)
    picture = request.FILES.get("another_picture", False)

    if request.user == pet.owner and request.method == "POST" and picture:
        models.Photo.objects.create(pet_id=pet.id, image=picture)

    return HttpResponseRedirect(reverse("meupet:detail", kwargs={"pk_or_slug": pet.slug}))


class SearchView(FormView):
    template_name = "meupet/search.html"
    form_class = SearchForm

    def form_valid(self, form):
        query = self._build_query(form.cleaned_data)

        pets = models.Pet.objects.actives().filter(query)
        return render(self.request, "meupet/search.html", {"form": form, "pets": pets})

    @staticmethod
    def _build_query(cleaned_data):
        query = Q()

        for key, value in cleaned_data.items():
            if value:
                query &= Q(**{key: value})

        return query


def registered(request, slug):
    context = {
        "pet_slug": slug,
        "facebook_url": settings.FACEBOOK_SHARE_URL.format(slug),
        "twitter_url": settings.TWITTER_SHARE_URL.format(slug),
    }
    return render(request, "meupet/registered.html", context)


def poster(request, slug):
    pet = get_object_or_404(models.Pet, slug=slug)
    return render(request, "meupet/poster.html", {"pet": pet})


def update_register(request, request_key):
    pet = get_object_or_404(models.Pet, request_key=request_key)
    pet.activate()
    return HttpResponseRedirect(pet.get_absolute_url())