Saya ingin membatasi akses ke URL yang ditangani oleh Django Generic Views.
Untuk Tampilan saya, saya tahu bahwa login_required
dekorator melakukan pekerjaan itu. Juga Buat / Hapus / Perbarui Tampilan Generik mengambil login_required
argumen, tetapi saya tidak dapat menemukan cara untuk melakukan ini untuk Tampilan Generik lainnya.
Django> = 1.9 atau menggunakan django-braces
Django 1.9 telah memperkenalkan sebuah LoginRequiredMixin yang digunakan sebagai berikut:
from django.contrib.auth.mixins import LoginRequiredMixin class MyView(LoginRequiredMixin, View): login_url = '/login/' redirect_field_name = 'redirect_to'
Jika Anda menggunakan versi lama dari django Anda dapat menggunakan campuran yang hampir sama dari django-braces - versi Django didasarkan pada versi django-braces. django-braces 1.4.x masih mendukung Django 1.4 sehingga Anda dapat menggunakannya dengan versi lama yang cantik.
Metode Lama
Saya menemukan pertanyaan ini saat mencari di Google tentang cara menghias tampilan berbasis kelas, jadi untuk menambahkan jawabannya:
Ini tercakup dalam bagian dokumentasi tentang mendekorasi tampilan berbasis kelas . Ada
urls.py
pembungkusnya, atau Anda dapat menerapkan dekorator kedispatch()
metode. Contoh dari dokumentasi:Dekorasi di conf 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())), )
Mendekorasi kelas
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)
Lihat dokumentasi yang ditautkan di atas untuk lebih jelasnya.
sumber
def dispatch
metode sebagai subkelasView
. Sekarang saya bisa membuat sesuatu seperti ini:class ProtectedTemplateView(TemplateView, ProtectedView): pass
Tampilan umum telah berubah dari fungsi ke objek dengan versi 1.3 dari Django. Karena itu, ada sedikit perubahan yang diperlukan agar jawaban Will McCutchen dan Will Hardy dapat berfungsi dengan versi 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'))), )
Juga dokumentasi menjelaskan bagaimana melakukan ini juga.
sumber
Jika Anda tidak ingin menulis pembungkus tipis Anda sendiri di sekitar tampilan umum yang dimaksud (seperti yang disarankan Aamir), Anda juga dapat melakukan sesuatu seperti ini di
urls.py
file Anda :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 )
sumber
Untuk django 1.11, Anda dapat menggunakan LoginRequiredMixin untuk Tampilan berbasis Kelas
di file pengaturan yang harus Anda tambahkan
LOGIN_URL="/login/"
di views.py Anda
from django.contrib.auth.mixins import LoginRequiredMixin class RestaurantLocationCreateView(LoginRequiredMixin,CreateView): ....
sumber
Cara lain untuk mencapai ini adalah di bawah, saya suka itu sangat mirip dengan cara melakukannya dengan tampilan berbasis fungsi dan tidak memerlukan modifikasi
urls.py
atau penggantiandispatch
:@method_decorator(login_required, name='dispatch') class YourGenericViewSubclass(TemplateView): # # View methods #
sumber
Saya menginginkan cara yang dapat digunakan kembali untuk meminta otorisasi pada banyak tampilan yang berasal dari tampilan umum. Saya membuat fungsi pengiriman pengganti yang dapat saya tambahkan ke kelas tampilan saya dengan cara yang sama seperti deklarasi lainnya.
class Index(generic.ListView): model = models.HomePage dispatch = auth.dispatch
auth.dispatch adalah tempat kami melakukan pekerjaan:
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
sumber
Dalam Django => 3.0 ini menjadi sangat mudah:
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'
untuk referensi: https://docs.djangoproject.com/en/3.0/topics/class-based-views/intro/#decorating-the-class
sumber
Gunakan yang berikut ini:
from django.contrib.auth.decorators import login_required @login_required def your_view(): # your code here
sumber
Berikut ini bisa menyelesaikan masalah ini.
// 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); } )
sumber
Saya telah berjuang untuk menemukan jawaban untuk ini untuk waktu yang lama sampai saya menemukan solusi ini.
Dalam models.py do: from django.db import model
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
Dalam forms.py lakukan:
from django import forms from .models import YourLoginModel class LoginForm(forms.ModelForm): class Meta: model = YourLoginModel fields = ('username', 'password')
Dalam logika login 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})
Dalam tampilan aplikasi Anda ingin melakukan login_required pada 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')
sumber