W przypadku Django <1.5 możesz dodać dekorator, opakowując funkcję w swoich adresach URL, co pozwala zawijać ogólne widoki:
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'}),
)
Ogólne widoki oparte na funkcjach są przestarzałe w Django 1.4 i zostały usunięte w Django 1.5. Ale obowiązuje ta sama zasada, po prostu zawiń funkcję widoku widoku opartego na klasach login_required
dekoratorem:
login_required(TemplateView.as_view(template_name='foo_index.html'))
Django> = 1.9 lub używając nawiasów klamrowych django
Django 1.9 wprowadził LoginRequiredMixin, który jest używany w ten sposób:
from django.contrib.auth.mixins import LoginRequiredMixin class MyView(LoginRequiredMixin, View): login_url = '/login/' redirect_field_name = 'redirect_to'
Jeśli używasz starszej wersji django, możesz użyć prawie tego samego miksu z nawiasów django - wersja Django została oparta na wersji django-nawiasach klamrowych. django-braces 1.4.x nadal obsługuje Django 1.4, więc możesz go używać z dość starymi wersjami.
Starsze metody
Znalazłem to pytanie podczas wyszukiwania w Google, jak udekorować widoki oparte na klasach, więc dodaję odpowiedź:
Jest to omówione w sekcji dokumentacji dotyczącej dekorowania widoków opartych na klasach . Jest
urls.py
opakowanie lub możesz zastosować dekorator dodispatch()
metody. Przykłady z dokumentacji:Dekorowanie w konf. URL
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())), )
Dekorowanie klasy
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)
Więcej informacji można znaleźć w dokumentacji, do której link znajduje się powyżej.
źródło
def dispatch
metodą jako podklasąView
. Teraz mogę po prostu zrobić coś takiego:class ProtectedTemplateView(TemplateView, ProtectedView): pass
Ogólne widoki zmieniły się z funkcji na obiekty w wersji 1.3 Django. W związku z tym wymagana jest niewielka zmiana, aby odpowiedzi Will McCutchen i Will Hardy działały z wersją 1.3:
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'))), )
Również dokumentacja opisuje, jak to zrobić, jak również.
źródło
Jeśli nie chcesz pisać własnego cienkiego opakowania wokół danych ogólnych widoków (jak zasugerował Aamir), możesz również zrobić coś takiego w swoim
urls.py
pliku: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 )
źródło
W przypadku django 1.11 możesz użyć LoginRequiredMixin dla widoków opartych na klasach
w pliku ustawień należy dodać
LOGIN_URL="/login/"
w twoim views.py
from django.contrib.auth.mixins import LoginRequiredMixin class RestaurantLocationCreateView(LoginRequiredMixin,CreateView): ....
źródło
Innym sposobem osiągnięcia tego jest poniżej, podoba mi się, że jest podobny do tego, jak to się robi z widokami opartymi na funkcjach i nie wymaga modyfikowania
urls.py
ani zastępowaniadispatch
:@method_decorator(login_required, name='dispatch') class YourGenericViewSubclass(TemplateView): # # View methods #
źródło
Chciałem, aby sposób wielokrotnego użytku wymagał uwierzytelniania w wielu widokach pochodzących z widoków ogólnych. Utworzyłem zastępczą funkcję wysyłania, którą mogę dodać do mojej klasy widoku w taki sam sposób, jak inne deklaracje.
class Index(generic.ListView): model = models.HomePage dispatch = auth.dispatch
auth.dispatch to miejsce, w którym wykonujemy pracę:
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
źródło
W Django => 3.0 robi się to całkiem proste:
from django.contrib.auth.decorators import login_required from django.utils.decorators import method_decorator from django.views.generic import TemplateView @method_decorator(login_required(login_url='/login/'), name='dispatch') class ProtectedView(TemplateView): template_name = 'secret.html'
dla odniesienia: https://docs.djangoproject.com/en/3.0/topics/class-based-views/intro/#decorating-the-class
źródło
Użyj następujących:
from django.contrib.auth.decorators import login_required @login_required def your_view(): # your code here
źródło
Poniższe informacje mogą rozwiązać ten problem.
// 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); } )
źródło
Przez długi czas zmagałem się ze znalezieniem odpowiedzi na to pytanie, dopóki nie znalazłem tego obejścia.
W models.py zrób: z django.db importuj modele
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
W forms.py wykonaj:
from django import forms from .models import YourLoginModel class LoginForm(forms.ModelForm): class Meta: model = YourLoginModel fields = ('username', 'password')
W logice logowania views.py:
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})
W widoku aplikacji chcesz wykonać login_required na do
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')
źródło