BlackTrub
@BlackTrub
Костыль developer

Django Anonymous access?

Здравствуйте!
Имею следующую models.py:
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User

class Article(models.Model):
    article_title = models.CharField(max_length=100)
    article_text = models.TextField()
    article_date_create = models.DateTimeField(default=timezone.now)
    article_date_modify = models.DateTimeField(default=timezone.now)
    article_access = models.BooleanField(default=True)
    article_autor = models.ForeignKey(User)
    article_tag = models.ManyToManyField(Tags)

Article_access - отвечает за доступ к статье анонимными пользователями.
Доступ к конкретной статье реализован так views.py:
from django.views import generic

class FullView(generic.DetailView):
    template_name = 'blog/full.html'
    model = Article
    context_object_name = 'fullpost_blog'

Мне нужно ограничить доступ анонимного пользователя только к закрытым постам, реализация с помощью декоратора. Пробовал использовать @login_required, но тогда анонимный пользователь не может открыть вообще не одну статью, так же пробовал @permission_required, но там я так понял нужно именно права, а моё 'Article.article_access' он не воспринимает.
Пожалуйста подскажите в какую сторону двигаться, мне нужно написать свой декоратор или же как-то отлавливать когда открывают именно закрытый пост?
  • Вопрос задан
  • 931 просмотр
Решения вопроса 4
sim3x
@sim3x
Используем
https://docs.djangoproject.com/en/1.9/ref/contrib/...
возможно стоит сделать лендинг для таких пользователей, где б они могли авторизироваться или создать акк
stackoverflow.com/questions/5433172/how-to-redirec...

ну и добавить гет пареметр next stackoverflow.com/a/13595154
Ответ написан
Есть два варианта.

1. Раздать всем зарегистрированным пользователям специально созданный permission - например, Article.can_view, скажем, посредством добавления их всех в группу, и затем использовать permission_required.

2. (Мне кажется, лучше) переопределить get_object во view приблизительно так:

obj = super(FullView, self).get_object()
if self.request.user.is_anonymous and obj.article_access:
    raise PermissionDenied
else:
    return obj
Ответ написан
@bpe
1. Из вопроса не очень понятно, как должна обрабатываться ситуация если анонимный пользователь зашел на страницу с записью на просмотр которой у него нет прав. Стандартный вариант - он видит сообщение: "Данная запись доступна только зарегистрированным пользователям, войдите или зарегистрируйтесь". "войдите" и "зарегистрируйтесь" соответственно ссылки. При article_access = True запись отображается для анонимного или нет? Допустим, что если article_access = True то запись доступна для анонимного пользователя. Тогда в шаблоне:

{% if user.is_authenticated or article.article_access %}
    <p>{{ article.article_title }}</p>
    <p>{{ article.article_text }}</p>
    ...
{% else %}
    <p>"Данная запись доступна только зарегистрированным пользователям, <a href="{% url 'customer:login' %}">войдите</a> или
        <a href="{% url 'customer:register' %}">зарегистрируйтесь".</a></p>
{% endif %}

2. Избавиться от generic view и сделать FBV:
if request.user.is_authenticated():
...
else:
...


3. Перекрыть какой то из методов DetailView проверить тот же request.user.is_authenticated() и вернуть нужный Queryset. В этом случае FBV будет компактней и проще.
Ответ написан
BlackTrub
@BlackTrub Автор вопроса
Костыль developer
Всем огромное спасибо за помощь!

Решил проблему написанием своего декоратора.
И так views.py:
def FullView(request, pk):
    obj = get_object_or_404(Article, pk=pk)

    @access_private_post(url='/login', access=obj.article_access)
    def view(request, obj):
        return render(request, 'blog/full.html', {'fullpost_blog': obj})

    return view(request, obj)

И сам декоратор decorators.py:
from functools import wraps
from django.shortcuts import redirect


def access_private_post(function=None, url=None, access=None):
    def decorator(function):
        @wraps(function)
        def wrapper(request, *args, **kwargs):
            if not access and not request.user.is_authenticated():
                return redirect(url)
            else:
                return function(request, *args, **kwargs)
        return wrapper
    return decorator


Вьюшка к сожалению пока выглядит не очень, но это я доработаю, всем ещё раз спасибо!
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы