Complete worked example
python
from bootstrap_lab import django_setup
django_setup(__name__)
from bootstrap_lab import install_models
from django.contrib.auth import get_user_model
from django.db import models
class Role(models.Model):
title = models.CharField(max_length=80)
owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
class Meta:
app_label = "framework_lab"
install_models(Role)
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from django.test import Client
from django.urls import path
@login_required
def detail(request, role_id):
role = get_object_or_404(Role, pk=role_id, owner=request.user)
return JsonResponse({"title": role.title})
urlpatterns = [path("roles/<int:role_id>/", detail)]
def object_request(actor, role_id):
Role.objects.all().delete()
User = get_user_model()
User.objects.all().delete()
owner = User.objects.create_user(username="owner")
other = User.objects.create_user(username="other")
Role.objects.create(id=1, title="Private engineer role", owner=owner)
client = Client()
if actor != "guest":
client.force_login(owner if actor == "owner" else other)
response = client.get(f"/roles/{role_id}/")
return {"status": response.status_code, "body": response.json() if response.status_code == 200 else None}- Reasoning
- The protected view performs its lookup with both the requested primary key and request.user as owner. That combines object identity and permission scope before serialization.