【问题标题】:How can I restrict user to to view only specific page having a dynamic URL?如何限制用户仅查看具有动态 URL 的特定页面?
【发布时间】:2021-09-27 06:18:49
【问题描述】:

我正在做一个项目,其中我为员工详细信息创建了一个模型表单。现在,我希望用户能够通过员工表单仅更新他们的记录,并且此员工表单的 URL 是动态的。

在这个项目中,我从 views.py 填充用户身份验证模型,并且没有提供从前端创建用户的选项,因为不提供从前端创建用户的选项背后的想法是创建当有人创建新的员工记录时,用户自动生成。

因此,要为最近创建记录的员工填充用户身份验证模型。我在名字、姓氏和主键上应用连接来生成用户名,而对于密码,我正在生成一个随机密码。

在主页上,我生成了员工记录的列表视图,还提供了一个查看链接(查看特定员工的完整详细信息)和另一个用于更新记录的链接,它是一个动态 URL(update/ /).

现在,我希望用户只能更新他的记录而不是其他人的记录,这是我正在努力解决的部分。

models.py

from django.db import models

# Create your models here.

class Department(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

class Designation(models.Model):
    name = models.CharField(max_length=50)
    department_id = models.ForeignKey(Department, on_delete=models.CASCADE, default='')

    def __str__(self):
        return self.name

class Country(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

class State(models.Model):
    name = models.CharField(max_length=50)
    country_id = models.ForeignKey(Country, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

class City(models.Model):
    name = models.CharField(max_length=50)
    state_id = models.ForeignKey(State, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

class Employee(models.Model):
    emp_id = models.AutoField(primary_key=True)
    emp_first_name = models.CharField(max_length=50)
    emp_last_name = models.CharField(max_length=50, default='')
    email = models.EmailField()
    salary = models.IntegerField()
    joining_date = models.DateField()
    department = models.ForeignKey(Department, on_delete=models.SET_NULL, null=True)
    designation = models.ForeignKey(Designation, on_delete=models.SET_NULL, null=True)
    country = models.ForeignKey(Country, on_delete=models.SET_NULL, null=True)
    state = models.ForeignKey(State, on_delete=models.SET_NULL, null=True)
    city = models.ForeignKey(City, on_delete=models.SET_NULL, null=True)
    # system generated password when created the record
    sys_gen_pass = models.CharField(max_length=50, blank=True)

    def __str__(self):
        return self.emp_name

forms.py

from bootstrap_datepicker_plus import DatePickerInput
from django import forms
from .models import Employee

class EmployeeForm(forms.ModelForm):
    class Meta:
        model= Employee
        fields= '__all__'

        widgets = {
            'joining_date': DatePickerInput(),
        }

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('home/', views.home, name='home'),
    path('new/', views.new, name='new'),
    path('detail/<int:id>/', views.detail, name='detail'),
    path('delete/<int:id>/', views.delete, name='delete'),
    path('update/<int:id>/', views.update, name='update'),
    path('load_state/', views.load_state, name='load_state'),
    path('load_city/', views.load_city, name='load_city'),
    path('load_designation/', views.load_designation, name='load_designation'),
    path('loginuser/', views.loginuser, name='loginuser'),
    path('logoutuser/', views.logoutuser, name='logoutuser'),
]

views.py

from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required, permission_required
from .forms import EmployeeForm
from .models import *
import random

# Create your views here.

def home(request):
    emp = Employee.objects.all()
    return render(request, 'home.html', {'employees': emp})

def new(request):
    if request.method == 'GET':
        form = EmployeeForm
        return render(request, 'new.html', {'form': form})
    else:
        form = EmployeeForm(request.POST)
        if form.is_valid():
            # here I am generating a password for every employee created
            string = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~!@#$%^&*()_=+-[]{};:,./<>?"
            password_length = 12
            password = "".join(random.sample(string, password_length))
            form.save()
            # here I am updating the password in model
            latest=Employee.objects.last()
            latest.sys_gen_pass = password
            latest.save()
            # here I am creating user for which I have just added a record
            # the user_name = First_name+last_name+PrimaryKey and the password will be what I have just created
            # for that I am removing the spaces from Employee_Name field
            def remove(string):
                return string.replace(" ", "")
            e_name = remove(latest.emp_first_name) + remove(latest.emp_last_name) + str(latest.emp_id)
            e_email = latest.email
            user_password = latest.sys_gen_pass
            # Creating user and saving it to the database
            user = User.objects.create_user(e_name, e_email, user_password)
            user.first_name = latest.emp_first_name
            user.last_name  = latest.emp_last_name
            user.save()
            return redirect('home')

def loginuser(request):
    if request.method == 'GET':
        return render(request, 'loginuser.html', {'form': AuthenticationForm})
    else:
        user = authenticate(request, username=request.POST['username'], password=request.POST['password'],)
        if user is None:
            return render(request, 'loginuser.html', {'form': AuthenticationForm, 'error': 'user does not exist or invalid password'})
        else:
            login(request, user)
            return redirect('home')

def logoutuser(request):
    if request.method == "POST":
        logout(request)
        return redirect('home')


def detail(request, id):
    emp_details = Employee.objects.get(pk = id)
    return render(request, 'detail.html', {'emp_details': emp_details})

def delete(request, id):
    emp_remove = Employee.objects.get(pk = id)
    emp_remove.delete()
    # return render(request, 'delete.html')
    return redirect('home')

@login_required(login_url='loginuser')
# @permission_required(login_url='')
def update(request, id):
    emp_id = Employee.objects.get(pk=id)
    if request.method == 'GET':
        form = EmployeeForm(instance=emp_id)
        return render(request, 'update.html', {'form': form})
    else:
        form = EmployeeForm(request.POST, instance=emp_id)
        if form.is_valid():
            form.save()
            print(id)
            return redirect('detail', id = id)
            # return redirect('detail/', id = emp_id)
    return render(request, 'update.html', {'form': form})

def load_designation(request):
    # print('designation')
    department_id = request.GET.get('department')
    designations = Designation.objects.filter(department_id = department_id).order_by('name')
    return render(request, 'load_designation.html', {'designations': designations})

def load_state(request):
    # print('state')
    country_id = request.GET.get('country')
    states = State.objects.filter(country_id = country_id).order_by('name')
    return render(request, 'load_state.html', {'states': states})

def load_city(request):
    # print('city')
    state_id = request.GET.get('state')
    cities = City.objects.filter(state_id = state_id).order_by('name')
    return render(request, 'load_city.html', {'cities': cities})

【问题讨论】:

    标签: python django django-authentication django-permissions dynamic-url


    【解决方案1】:

    我没有仔细阅读你的代码,因为它有很多东西要看。

    我相信你描述的最后一行是你的问题。

    现在,我希望用户只能更新他的记录而不是某人 其他的,这是我正在努力的部分。

    答案是,在员工记录的列表视图中,您应该只显示该特定用户的记录,以便他只能更新他的记录。 希望对你有帮助。

    【讨论】:

    • 我希望用户看到列表但不能更新其他记录。
    • 那么 Django Permissions 是最好的方法。查看链接答案:https://stackoverflow.com/questions/33400830/restrict-update-method-to-only-modify-request-users-own-data
    • 感谢链接在浏览链接时得到了这个想法。这就是我所做的......
    【解决方案2】:

    您可以使用“更新信息”按钮向用户显示包含其数据的页面,以便他们更新数据。您应该只显示请求该页面的用户的数据,当他们更改数据时,它应该只将更改保存到他们的数据中,而不是任何其他用户的数据。

    在显示用户信息的模板中,您应该首先检查用户是请求自己的信息还是其他用户的信息。显示请求用户的数据后,使用 if 条件,如果用户请求自己的信息,“更新信息”按钮将显示,如果用户请求其他用户的信息,“更新信息”按钮将不会显示。

    【讨论】:

      【解决方案3】:
      @login_required(login_url='loginuser')
      def update(request, sys_gen_user):
      
          # here I am getting the user name of current logged in user.
          if request.user.is_authenticated:
              username = request.user.username
      
          # comparing with the user_name(sys_gen_user) saved in Employee Table with the user name of current logged in user.
          if username == sys_gen_user:
              emp_id = Employee.objects.get(sys_gen_user=sys_gen_user)
              if request.method == 'GET':
                  form = EmployeeForm(instance=emp_id)
                  return render(request, 'update.html', {'form': form})
              else:
                  form = EmployeeForm(request.POST, instance=emp_id)
                  if form.is_valid():
                      form.save()
      

      【讨论】:

        猜你喜欢
        • 2010-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-20
        • 2018-07-21
        • 2023-03-19
        • 2018-08-01
        • 2014-09-28
        相关资源
        最近更新 更多