Django Genel Görünümler için nasıl oturum açılmalı?


88

Django Genel Görünümler tarafından işlenen URL'lere erişimi kısıtlamak istiyorum.

Görüşlerim için işi login_requireddekoratörün yaptığını biliyorum . Ayrıca Genel Görünümleri Oluştur / Sil / Güncelle login_requiredargümanı alıyor, ancak bunu diğer Genel Görünümler için yapmanın bir yolunu bulamadım.

Yanıtlar:


104

Django <1.5 için, işlevi url'lerinize sararak bir dekoratör ekleyebilirsiniz, bu da genel görünümleri kaydırmanıza olanak tanır:

from django.contrib.auth.decorators import login_required
from django.views.generic.simple import direct_to_template
urlpatterns = patterns('',
    (r'^foo/$', login_required(direct_to_template), {'template': 'foo_index.html'}),
    )

İşlev tabanlı genel görünümler, Django 1.4'te kaldırılmıştır ve Django 1.5'te kaldırılmıştır. Ancak aynı ilke geçerlidir, sadece sınıf tabanlı görünümün görünüm işlevini login_requireddekoratörle kaydırın:

login_required(TemplateView.as_view(template_name='foo_index.html'))

Burada login_url login_required (TemplateView.as_view (template_name = 'foo_index.html')) nasıl belirtilir
Saisiva A

103

Django> = 1.9 veya django-parantez kullanma

Django 1.9, şu şekilde kullanılan bir LoginRequiredMixin'i tanıttı :

from django.contrib.auth.mixins import LoginRequiredMixin

class MyView(LoginRequiredMixin, View):
    login_url = '/login/'
    redirect_field_name = 'redirect_to'

Django'nun daha eski bir sürümünü kullanıyorsanız, django-braces ile hemen hemen aynı mixini kullanabilirsiniz - Django sürümü, django-braces sürümüne dayanıyordu. django-braces 1.4.x hala Django 1.4'ü desteklemektedir, böylece onu oldukça eski sürümlerle kullanabilirsiniz.

Eski Yöntemler

Bu soruyu, sınıfa dayalı görünümleri nasıl dekore edeceğimi araştırırken buldum, bu yüzden bunun cevabını eklemek için:

Bu, sınıfa dayalı görünümlerin dekorasyonuyla ilgili dokümantasyon bölümünde ele alınmıştır . urls.pySarıcı var veya dekoratörü dispatch()yönteme uygulayabilirsiniz . Belgelerden örnekler:

URL yapılandırmasında dekorasyon

from django.contrib.auth.decorators import login_required, permission_required
from django.views.generic import TemplateView

from .views import VoteView

urlpatterns = patterns('',
    (r'^about/', login_required(TemplateView.as_view(template_name="secret.html"))),
    (r'^vote/', permission_required('polls.can_vote')(VoteView.as_view())),
)

Sınıfı dekore etmek

from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView

class ProtectedView(TemplateView):
    template_name = 'secret.html'

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(ProtectedView, self).dispatch(*args, **kwargs)

Daha fazla ayrıntı için yukarıda bağlantısı verilen belgelere bakın.


HARİKA! ancak def dispatchalt sınıfı olarak sadece yöntemle basit bir sınıf yaptım View. Şimdi basitçe şöyle bir şey yapabilirim:class ProtectedTemplateView(TemplateView, ProtectedView): pass
WBAR

login_url'yi ayarlamaz, ancak bunu settings.py'de ayarlarsam, varsayılan olarak buna yönlendirir mi?
Marat Mkhitaryan

38

Genel görünümler, Django'nun 1.3 sürümü ile işlevlerden nesnelere değişti. Bu nedenle, Will McCutchen ve Will Hardy'nin 1.3 sürümüyle çalışmak için yanıt vermesi gereken küçük bir değişiklik var:

from django.contrib.auth.decorators import login_required
from django.views.generic import TemplateView

urlpatterns = patterns('',
    (r'^foo/$', login_required(TemplateView.as_view(template_name='foo_index.html'))),
)

Belgeler ayrıca bunun nasıl yapılacağını da açıklamaktadır.


2
Lütfen okuyucu, bu cevabı dikkate alınız çünkü zaman geçmektedir ve yazılım gelişmektedir. İlk çözüm benim için işe yaramadı.
n3storm

12

Söz konusu genel görünümlerin etrafına kendi ince paketleyicinizi yazmak istemiyorsanız (Aamir'in önerdiği gibi), urls.pydosyanızda şöyle bir şey de yapabilirsiniz :

from django.conf.urls.defaults import *

# Directly import whatever generic views you're using and the login_required
# decorator
from django.views.generic.simple import direct_to_template
from django.contrib.auth.decorators import login_required

# In your urlpatterns, wrap the generic view with the decorator
urlpatterns = patterns('',
    (r'', login_required(direct_to_template), {'template': 'index.html'}),
    # etc
)

8

Django 1.11 için, Sınıf Tabanlı Görünümler için LoginRequiredMixin'i kullanabilirsiniz.

ayarlar dosyasında eklemelisiniz

LOGIN_URL="/login/"

views.py içinde

from django.contrib.auth.mixins import LoginRequiredMixin

class RestaurantLocationCreateView(LoginRequiredMixin,CreateView):
    ....

8

Bunu başarmanın bir başka yolu da aşağıdadır, işlev tabanlı görünümlerle nasıl yapıldığına oldukça benzer olmasını ve değiştirmeyi urls.pyveya geçersiz kılmayı gerektirmemesini seviyorum dispatch:

@method_decorator(login_required, name='dispatch')
class YourGenericViewSubclass(TemplateView):
    #
    # View methods
    #

3

Genel görünümlerden türetilen birçok görünümde yetkilendirmeyi gerektirmenin yeniden kullanılabilir bir yolunu istedim. Görünüm sınıfıma diğer bildirimlerle aynı şekilde ekleyebileceğim bir yedek gönderme işlevi oluşturdum.

class Index(generic.ListView):
    model = models.HomePage
    dispatch = auth.dispatch

auth.dispatch işi yaptığımız yerdir:

def dispatch(self, request, *args, **kw):
    """Mix-in for generic views"""
    if userSession(request):
        return  super(self.__class__, self).dispatch(request, *args, **kw)

    # auth failed, return login screen
    response = user(request)
    response.set_cookie('afterauth', value=request.path_info)
    return response


1

Aşağıdakileri kullanın:

from django.contrib.auth.decorators import login_required

@login_required
def your_view():
    # your code here

5
Sorunun tarihine dayanarak, OP'nin django'nun sınıf temelli genel görüşleri için bir çözüm istediğini varsayıyorum ... işlev temelli görüşler değil.
Dolph

0

Aşağıdakiler bu sorunu çözebilir.

// in views.py:
class LoginAuthenAJAX(View):
    def dispatch(self, request, *args, **kwargs):
        if request.user.is_authenticated:
            jsonr = json.dumps({'authenticated': True})
        else:
            jsonr = json.dumps({'authenticated': False})
        return HttpResponse(jsonr, content_type='application/json')

// in urls.py
    path('login_auth', views.LoginAuthenAJAX.as_view(), name="user_verify"),

//in xxx.html
<script src = “{% static “xxx/script.js” %}” 
var login_auth_link = “{%  url ‘user_verify’ %}”
</script>

// in script.js
        $.get(login_auth_link, {
            'csrfmiddlewaretoken' : csrf_token,
            },
            function(ret){
                if (ret.authenticated == false) {
                    window.location.pathname="/accounts/login/"
                }
                $("#message").html(ret.result);
            }
        )

0

Bu geçici çözümü bulana kadar uzun süredir bunun cevabını bulmakta zorlanıyordum.

Models.py do: django.db'den içe aktarma modelleri

class YourLoginModel:
      fullname = models.CharField(max_length=255, default='your_name', unique=True)
      email  = models.EmailField(max_length=255, unique=True)
      username = models.CharField(max_length=255, unique=True)
      password = models.CharField(max_length=255) #using werkzeug's 
                                                  #generate_password_hash on plaintext password before committing to database model

Forms.py'da şunları yapın:

from django import forms
from .models import YourLoginModel

class LoginForm(forms.ModelForm):
      class Meta:
            model = YourLoginModel
            fields = ('username', 'password')

Views.py oturum açma mantığında:

def login(request):
    #login logic here
     # init empty form
    form = LoginForm()

    if request.method == 'POST':

        try:
            # peforms a Select query in db and gets user with log in username
            user_logging_in = User.objects.get(username=request.POST['username'])

            # assign user hash to var
            hash = user_logging_in.password

            # assign form str passs word to var
            password = request.POST['password']

        # if the user does not exist
        except ObjectDoesNotExist:
            html_response = 'User does not exists'
            return HttpResponse(html_response)

        # peform password and hash check
        if check_password_hash(hash, password):
 
            #using sessions cookies to know who we're interacting with
            request.session['username'] = request.POST['username']

            #set expiry date of the session
            request.session.set_expiry(0) # 0 means when the browser is closed

            return redirect('yourapp:home')
        else:
            return HttpResponse('password was incorrect')

    html = 'Login'
    return render(request, 'login.html', {'form': form})

Uygulama görünümünde do üzerinde login_required gerçekleştirmek istiyorsunuz

from django.views.generic import TemplateView

class yourTemplateView(TemplateView):
      template_name = 'your_template.html'
      def dispatch(self, request, *args, **kwrags):
           if not request.session.has_key('username'):
              #return HttpResponse('not logged in')
              return redirect('yourapp:login.html')
           else:
              return render(request, 'your_view.html')
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.