Code: Select all
CustomUser
Code: Select all
change_product
Ich habe die Dokumentation von Django zum Erstellen eines benutzerdefinierten Elements befolgt Benutzermodell, aber ich vermute, dass es eine Fehlkonfiguration oder einen Schritt gibt, den ich übersehen habe. Hier ist die detaillierte Einrichtung:
Benutzerdefiniertes Benutzermodell und Manager (in der Userauths-App):
Unten ist der Code für mein benutzerdefiniertes Benutzermodell und seinen Manager:
Code: Select all
# userauths/models.py
from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.db import models
from django.utils.translation import gettext_lazy as _
class CustomUserManager(BaseUserManager):
def _create_user(self, email, password=None, **extra_fields):
if not email:
raise ValueError('The given email must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, password=None, **extra_fields):
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password=None, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
if not extra_fields.get('is_staff'):
raise ValueError('Superuser must have is_staff=True.')
if not extra_fields.get('is_superuser'):
raise ValueError('Superuser must have is_superuser=True.')
return self._create_user(email, password, **extra_fields)
class CustomUser(AbstractUser):
username = None
email = models.EmailField(_('email address'), unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = CustomUserManager()
In meiner Settings.py habe ich die folgende Zeile, um das benutzerdefinierte Benutzermodell anzugeben:
Code: Select all
AUTH_USER_MODEL = 'userauths.CustomUser'
Hier ist das Produkt-Modell befindet sich in der Kernanwendung:
Code: Select all
# core/models.py
from django.db import models
from shortuuidfield import ShortUUIDField
from django.utils.safestring import mark_safe
from ckeditor_uploader.fields import RichTextUploadingField
from taggit.managers import TaggableManager
from userauths.models import CustomUser # Importing the custom user model
class Product(models.Model):
pid = ShortUUIDField(length=10, max_length=100, prefix="prd", alphabet="abcdef")
user = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null=True)
title = models.CharField(max_length=100, default="Apple")
image = models.ImageField(upload_to="uploads/", default="product.jpg")
description = RichTextUploadingField(null=True, blank=True, default="This is a product")
price = models.DecimalField(max_digits=10, decimal_places=2, default=1.99)
old_price = models.DecimalField(max_digits=10, decimal_places=2, default=2.99)
status = models.BooleanField(default=True)
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
Hier ist die relevante Ansichtslogik zum Bearbeiten und Löschen eines Produkts:< /p>
Code: Select all
# useradmin/views.py
from django.shortcuts import get_object_or_404, redirect, render
from django.contrib.auth.decorators import login_required, user_passes_test
from core.models import Product
@login_required
@user_passes_test(lambda user: user.is_staff)
def edit_product(request, pid):
product = get_object_or_404(Product, pid=pid)
if request.method == "POST":
form = AddProductForm(request.POST, request.FILES, instance=product)
if form.is_valid():
form.save()
return redirect("useradmin:vendordashboard")
else:
form = AddProductForm(instance=product)
context = {"form": form, "product": product}
return render(request, "useradmin/edit-product.html", context)
@login_required
@user_passes_test(lambda user: user.is_staff)
def delete_product(request, pid):
product = get_object_or_404(Product, pid=pid)
product.delete()
return redirect("useradmin:vendordashboard")
- Ich habe das change_product zugewiesen und delete_product-Berechtigungen für den Benutzer über das Django-Admin-Panel.
- Der Benutzer wird als is_staff=True markiert.
- Trotzdem erhält der Benutzer die Fehlermeldung 403 Forbidden beim Versuch, auf die Ansichten edit_product oder delete_product zuzugreifen.
- Überprüft, ob die Berechtigungen korrekt zugewiesen wurden, mit:
Die richtigen Berechtigungen (z. B. core.change_product, core.delete_product) werden in der Ausgabe angezeigt.
Code: Select all
user.get_all_permissions()
- Bestätigt, dass das benutzerdefinierte Benutzermodell verwendet wird, indem Folgendes überprüft wird:
Dies gibt userauths.models.CustomUser aus.
Code: Select all
from django.contrib.auth import get_user_model print(get_user_model())
- Überprüfte den is_staff“ ist auf „True“ gesetzt.
- Es wurde versucht, @user_passes_test durch @permission_required zu ersetzen:
Dies führte auch zu einem 403 Forbidden-Fehler.
Code: Select all
from django.contrib.auth.decorators import permission_required @login_required @permission_required('core.change_product', raise_exception=True) def edit_product(request, pid): ...
Wenn ein Benutzer über die entsprechende Berechtigung „change_product oder delete_product verfügt, sollte er dazu in der Lage sein Zugriff auf die jeweiligen Ansichten.
Tatsächliches Verhalten:
Auch nach der Zuweisung der richtigen Berechtigungen geben die Ansichten einen 403 Forbidden-Fehler zurück.
< hr />
Umgebung:
- Django-Version: 5.1.3
- Python-Version: 3.12.5
- Datenbank: SQLite
- Apps:
für das benutzerdefinierte BenutzermodellCode: Select all
userauths
- für das Produktmodell
Code: Select all
core
Frage:
Was könnte diesen Fehler 403 Forbidden verursachen, obwohl der Benutzer über die erforderlichen Berechtigungen verfügt? Muss ich einen zusätzlichen Schritt ausführen, wenn ich ein benutzerdefiniertes Benutzermodell mit Berechtigungen verwende?