0

In Django I have model called Loans. I want users to be able to edit a loan created by someone else, but not if they created it themselves.

As a bonus, I would like staff members not to be able to edit loans that belong to other staff.

How can I do this? I really have no idea. I tried creating custom validation, then I tried a manger like this:

from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator
from core.models import User


class LoanManager(models.Manager):
    def create_loan(self, request, borrower, approved, start_date, term_in_months, principal, interest_rate_pa, **extra_fields):
        """Creates and saves a new loan"""
        print('USER========================================', request.user)

        if borrower != request.user:
            raise ValueError("Staff may not lend to themselves or other staff")

        return super(LoanManager, self).create(borrower=borrower, approved=approved, start_date=start_date, term_in_months=term_in_months, principal=principal, interest_rate_pa=interest_rate_pa,**extra_fields)


class Loans(models.Model):
    borrower = models.ForeignKey(User, on_delete=models.CASCADE)
    approved = models.BooleanField(default=False)
    start_date = models.DateField(auto_now_add=True)
    term_in_months = models.IntegerField(validators=[
            MaxValueValidator(360),
            MinValueValidator(24)
        ])
    principal = models.IntegerField(validators=[
            MaxValueValidator(1000000),
            MinValueValidator(2000)
        ])
    interest_rate_pa = models.DecimalField(max_digits=5, decimal_places=2)

    objects = LoanManager()

Nothing I do seems to prevent users creating loans for themselves and editing them!

HenryM
  • 5,557
  • 7
  • 49
  • 105
Davtho1983
  • 3,827
  • 8
  • 54
  • 105
  • Please fix your code formatting (`{}` button in the editor). You'll have to write such functionality yourself, it's not how admin works. – thebjorn May 18 '19 at 13:34
  • 1
    Not an exact duplicate, but I answered a similar question yesterday, I think you could find it useful: https://stackoverflow.com/questions/56191534/add-staff-user-permissions-in-admin-with-custom-user-model/56191659#56191659 – frnhr May 18 '19 at 15:16

1 Answers1

0

Use a mixin with the view. The example below should check if the current user is the borrower for the Loan object. If they are the same it prevents access.

class MyLoanMixin (object):
    permission_denied_message = "You may not modify your own loan"

    def dispatch (self, request, *args, **kwargs):
        if self.get_object().borrower == request.user:
            raise PermissionDenied(self.get_permission_denied_message())
        return super().dispatch(request, *args, **kwargs)

    def get_permission_denied_message(self):
        """
        Override this method to override the permission_denied_message attribute.
        """
        return self.permission_denied_message

    def handle_no_permission(self):
        if self.raise_exception:
            raise PermissionDenied(self.get_permission_denied_message())
        return redirect_to_login(self.request.get_full_path(), self.get_login_url(), self.get_redirect_field_name())
HenryM
  • 5,557
  • 7
  • 49
  • 105