class UpdateView(BaseUpdateView):
    template_name_suffix = '_form_update' def class_login_required(cls):
    if (not isinstance(cls, type)
            or not issubclass(cls, View)):
        raise ImproperlyConfigured(
            "class_login_required"
            " must be applied to subclasses "
            "of View class.")
    decorator = method_decorator(login_required)
    cls.dispatch = decorator(cls.dispatch)
    return cls def require_authenticated_permission(permission):

    def decorator(cls):
        if (not isinstance(cls, type)
                or not issubclass(cls, View)):
            raise ImproperlyConfigured(
                "require_authenticated_permission"
                " must be applied to subclasses "
                "of View class.")
        check_auth = (
            method_decorator(login_required))
        check_perm = (
            method_decorator(
                permission_required(
                    permission,
                    raise_exception=True)))

        cls.dispatch = (
            check_auth(check_perm(cls.dispatch)))
        return cls

    return decorator class NewsLinkForm(
        SlugCleanMixin, forms.ModelForm):
    class Meta:
        model = NewsLink
        fields = '__all__'
        widgets = {'startup': HiddenInput()} class StartupForm(
        SlugCleanMixin, forms.ModelForm):
    class Meta:
        model = Startup
        fields = '__all__' class TagForm(
        SlugCleanMixin, forms.ModelForm):
    class Meta:
        model = Tag
        fields = '__all__'

    def clean_name(self):
        return self.cleaned_data['name'].lower() class NewsLink(models.Model):
    title = models.CharField(max_length=63)
    slug = models.SlugField(max_length=63)
    pub_date = models.DateField('date published')
    link = models.URLField(max_length=255)
    startup = models.ForeignKey(Startup)

    objects = NewsLinkManager()

    class Meta:
        verbose_name = 'news article'
        ordering = ['-pub_date']
        get_latest_by = 'pub_date'
        unique_together = ('slug', 'startup')

    def __str__(self):
        return "{}: {}".format(
            self.startup, self.title)

    def get_absolute_url(self):
        return self.startup.get_absolute_url()

    def get_delete_url(self):
        return reverse(
            'organizer_newslink_delete',
            kwargs={
                'startup_slug': self.startup.slug,
                'newslink_slug': self.slug})

    def get_update_url(self):
        return reverse(
            'organizer_newslink_update',
            kwargs={
                'startup_slug': self.startup.slug,
                'newslink_slug': self.slug})

    def natural_key(self):
        return (
            self.startup.natural_key(),
            self.slug)
    natural_key.dependencies = [
        'organizer.startup']

    def description(self):
        return (
            "Written on "
            "{0:%A, %B} {0.day}, {0:%Y}; "
            "hosted at {1}".format(
                self.pub_date,
                urlparse(self.link).netloc)) class Startup(models.Model):
    name = models.CharField(
        max_length=31, db_index=True)
    slug = models.SlugField(
        max_length=31,
        unique=True,
        help_text='A label for URL config.')
    description = models.TextField()
    founded_date = models.DateField(
        'date founded')
    contact = models.EmailField()
    website = models.URLField(max_length=255)
    tags = models.ManyToManyField(Tag, blank=True)

    objects = StartupManager()

    class Meta:
        ordering = ['name']
        get_latest_by = 'founded_date'

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('organizer_startup_detail',
                       kwargs={'slug': self.slug})

    def get_delete_url(self):
        return reverse('organizer_startup_delete',
                       kwargs={'slug': self.slug})

    def get_feed_atom_url(self):
        return reverse(
            'organizer_startup_atom_feed',
            kwargs={'startup_slug': self.slug})

    def get_feed_rss_url(self):
        return reverse(
            'organizer_startup_rss_feed',
            kwargs={'startup_slug': self.slug})

    def get_newslink_create_url(self):
        return reverse(
            'organizer_newslink_create',
            kwargs={'startup_slug': self.slug})

    def get_update_url(self):
        return reverse('organizer_startup_update',
                       kwargs={'slug': self.slug})

    @cached_property
    def published_posts(self):
        return tuple(self.blog_posts.filter(
            pub_date__lt=date.today()))

    def natural_key(self):
        return (self.slug,) class Tag(models.Model):
    name = models.CharField(
        max_length=31, unique=True)
    slug = models.SlugField(
        max_length=31,
        unique=True,
        help_text='A label for URL config.')

    objects = TagManager()

    class Meta:
        ordering = ['name']

    def __str__(self):
        return self.name.title()

    def get_absolute_url(self):
        return reverse('organizer_tag_detail',
                       kwargs={'slug': self.slug})

    def get_delete_url(self):
        return reverse('organizer_tag_delete',
                       kwargs={'slug': self.slug})

    def get_update_url(self):
        return reverse('organizer_tag_update',
                       kwargs={'slug': self.slug})

    @cached_property
    def published_posts(self):
        return tuple(self.blog_posts.filter(
            pub_date__lt=date.today()))

    def natural_key(self):
        return (self.slug,) class NewsLinkGetObjectMixin():

    def get_object(self, queryset=None):
        startup_slug = self.kwargs.get(
            self.startup_slug_url_kwarg)
        newslink_slug = self.kwargs.get(
            self.slug_url_kwarg)
        return get_object_or_404(
            NewsLink,
            slug__iexact=newslink_slug,
            startup__slug__iexact=startup_slug) class PageLinksMixin:
    page_kwarg = 'page'

    def _page_urls(self, page_number):
        return "?{pkw}={n}".format(
            pkw=self.page_kwarg,
            n=page_number)

    def first_page(self, page):
        # don't show on first page
        if page.number > 1:
            return self._page_urls(1)
        return None

    def previous_page(self, page):
        if (page.has_previous()
                and page.number > 2):
            return self._page_urls(
                page.previous_page_number())
        return None

    def next_page(self, page):
        last_page = page.paginator.num_pages
        if (page.has_next()
                and page.number < last_page - 1):
            return self._page_urls(
                page.next_page_number())
        return None

    def last_page(self, page):
        last_page = page.paginator.num_pages
        if page.number < last_page:
            return self._page_urls(last_page)
        return None

    def get_context_data(self, **kwargs):
        context = super().get_context_data(
            **kwargs)
        page = context.get('page_obj')
        if page is not None:
            context.update({
                'first_page_url':
                    self.first_page(page),
                'previous_page_url':
                    self.previous_page(page),
                'next_page_url':
                    self.next_page(page),
                'last_page_url':
                    self.last_page(page),
            })
        return context class StartupContextMixin():
    startup_slug_url_kwarg = 'startup_slug'
    startup_context_object_name = 'startup'

    def get_context_data(self, **kwargs):
        if hasattr(self, 'startup'):
            context = {
                self.startup_context_object_name:
                    self.startup,
            }
        else:
            startup_slug = self.kwargs.get(
                self.startup_slug_url_kwarg)
            startup = get_object_or_404(
                Startup,
                slug__iexact=startup_slug)
            context = {
                self.startup_context_object_name:
                    startup,
            }
        context.update(kwargs)
        return super().get_context_data(**context)
from django.core.urlresolvers import reverse_lazy
from django.shortcuts import get_object_or_404
from django.views.generic import (
    CreateView, DeleteView, DetailView, ListView)
from core.utils import UpdateView
from user.decorators import (
    class_login_required,
    require_authenticated_permission)
from .forms import (
    NewsLinkForm, StartupForm, TagForm)
from .models import NewsLink, Startup, Tag
from .utils import (
    NewsLinkGetObjectMixin, PageLinksMixin,
    StartupContextMixin)




@require_authenticated_permission(
    'organizer.add_newslink')
class NewsLinkCreate(
        NewsLinkGetObjectMixin,

        StartupContextMixin,