Как сделать общие представления Django доступными только для зарегистрированных пользователей?

#python #django #django-socialauth

#python #django #django-socialauth

Вопрос:

Я внедрил social-auth для Google, чтобы пользователи могли входить в систему. Я не могу понять, как ограничить доступ посетителей к общим представлениям, таким как UpdateView, ListView или CreateView, если они не вошли в систему с помощью системы социальной авторизации. Вот код.

views.py

 class AchievementCreate(CreateView):
    form_class = AchievementForm2
    model = Achievements
    def form_valid(self, form):
            achieves = form.save(commit=False)
            achieves.resume = Resume.objects.get(pk=2)
            return super(AchievementCreate, self).form_valid(form)

def home(request):
#logout(request)
    uname=""
    if request.method == 'POST' and 'submit' in request.POST:
        submit = request.POST['submit']
        if submit=="sign-out":
            logout(request)

    if '_auth_user_id' in request.session:
        uname=sm.UserSocialAuth.objects.get(
        user_id=int(request.session['_auth_user_id'])
        ).user
        request.session['uname']=str(uname)
    return render(request,'cv/home.html',{'uname': uname})
  

home.html

  <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8"/>
        <title>Home</title>
    </head>
    <body>
        <form method="post" action="{% url 'cv:home' %}">{% csrf_token %}
            {% if uname %}
                Helo, {{uname}}<br>
                The user already signed in. He may need to sign out<br>
                <input type="submit" name="submit" value="sign-out">            
            {% else %}
                Please sign-in<br>
                <a href="{% url 'social:begin' 'google-oauth2' %}">Google login</a>
            {% endif %}  
        </form> 
    </body>
    </html>
  

urls.py

 urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^achievements/(?P<pk>[0-9] )/delete/$', views.AchievementDelete.as_view(), name='achievement-delete'),
url(r'^achievements/(?P<pk>[0-9] )/$', views.AchievementUpdate.as_view(), name='achievement-update'),
url(r'^achievements/add/$', login_required(views.AchievementCreate.as_view()), name='achievement-add'),
url(r'^home/$', views.home, name='home'),]
  

Я хочу, чтобы класс «AchievementCreate» был доступен только в том случае, если пользователь вошел в систему. Но я не понимаю, как. Можно ли использовать сеансы? Как в этом случае?

Комментарии:

1. login_required Декоратор не работает?

2. Нет. Это не так.

Ответ №1:

Нам нужно написать mixins, чтобы проверить, вошел ли пользователь в систему или нет.

В Django 1.9 введен LoginRequiredMixin:

 from django.contrib.auth.mixins import LoginRequiredMixin

class UserProfile(LoginRequiredMixin, View):
    login_url = '/login/'
  

Следующий код представляет собой пользовательский mixin, который проверяет, активен или неактивен пользователь. Если пользователь неактивен, он выйдет из сеанса. Нам нужно записать микшины в отдельный файл, например mixins.py , импортировать микшины в представлениях

 class UserMixin(object):
    def dispatch(self, request, *args, **kwargs):
        user = self.request.user
        if user:
            if user.is_active:
                return super(UserMixin, self).dispatch(request, *args, **kwargs)
            else:
                logout(self.request)
        return HttpResponseRedirect(reverse('cv:home'))
  

В Views.py

 from mixins.py import UserMixin 

class UserEdit(UserMixin, View):
    model = UserProfile
    template_name = "dashboard/edit_user.html"
  

Ответ №2:

Вам нужно импортировать декоратор login_required и поместить @login_reqired перед представлением. Это представление будет доступно только при входе в систему.

Пример:

     from django.contrib.auth.decorators import login_required
    @login_required
    #put your view here
  

Комментарии:

1. Вы использовали его в своем views.py или просто перед видом в url.py ?

2. Я использовал это, и это сработало. @method_decorator(login_required) def dispatch(self, * аргументы, ** kwargs): возвращает super(AchievementCreate, self).dispatch(* аргументы, ** kwargs)

3. Есть ли какой-либо способ получить доступ к «request.session [‘uname’]» внутри общего класса представления?

4. Я использую модель auth_user из django, и все, что мне нужно вызвать, это request.user.<attribute>

5. Когда я пытаюсь это сделать, я получаю сообщение «запрос глобального имени не определен».

Ответ №3:

Итак, вы используете «social-auth» для своей системы входа. В вашем случае вам придется использовать пользовательскую функцию. Я предполагаю, что вы можете получить доступ к зарегистрированному пользователю, обратившись к: request.SESSION

Если это так, то вы можете переопределить метод отправки вашего CreateView:

 class AchievementCreate(CreateView):
   .....
   .....
   def dispatch(self, request, *args, **kwargs):
      user = request.session['_auth_user_id']
      # handle authentication
  

Ответ №4:

 def home(request):

    if request.user.is_authenticated:
        # Do something for authenticated users

    else:
        # Do something for anonymous users
  

https://docs.djangoproject.com/en/3.1/topics/auth/default/#authentication-in-web-requests