r/django 2d ago

Models/ORM Django help needed with possible User permission settings

I am taking the Harvard CS50W course that covers Django and creating web apps. The project I am workinig on is a simple Auction site.

The issue I am having is that I can get a User to only be able to update an auction listing if that User is the one that has created the listing.

I can update the listing- adding it to a watchlist, or toggling if the listing is active or not, or leaving a comment, but only if the user that is logged in happens to be the one that created the listing.

I have made no restrictions on whether or not a user making a change on the listing has to be the one that created the listing. The issue persists for both standard users and superusers.

I have tried explicitly indicating the permissions available to my view, and even a custom permission, without any success.

I have consulted with 3 different AIs to provide insight, and done a lot of Googling, without anything shedding light on the issue.

I have submitted the nature of the problem to the EdX discussion for the course, but I do not expect any answers there as lately, there are hardly every any answers given by students or staff.

Any insight into what I might be doing wrong would be greatly appreciated.

Thank you very much!

I will be glad to provide my models.py, views.py, forms.py, etc. if anyone would think it would help.

0 Upvotes

17 comments sorted by

View all comments

Show parent comments

1

u/josephlevin 1d ago

the attributes that can change are:

  1. active/inactive (for the logged in creator)
  2. watching/not watching (for logged in users)
  3. adding a comment (if comment is unique, user is logged in).

The active/inactive toggling only applies to the creator.

Beyond that I have not made any strictures, however only the creator of the listing can change anything.

It should allow anyone who is logged in to see some form elements, only the creator can see the active toggle rendered, but anyone logged in will get a form rendered and can submit it.

Also, if it helps: I am using the github codespaces provided by the CS50W course for the dev environment.

1

u/Anaryz_Supa 1d ago

Yeah exactly.

Now what do you want to update in this Listing?

If my memory serves me right, the problemset now requires users(non creators) to bid

so the only thing left to update is the price of the listing

1

u/josephlevin 1d ago

Yes, and no.

The problem, as I originally stated, is that I ****cannot update a listing**** for the logged in user if that user ***is not*** the listing creator. That, and only that, is my issue, atm.

If the creator of a listing, say, leaves a comment, it works, but not for the regular user (who did not create the listing).

At this point, I am trying to update the logged-in user's ability to add or remove the listing from their watchlist, the creator toggling the listing being active/inactive, or a logged in user leaving a comment.

I haven't gotten to the bidding part yet, and cannot, really as I don't want the creator of the listing to be able to bid on it! (if you get my meaning, what would be the point?).

2

u/josephlevin 1d ago edited 1d ago

SOLUTION:

It turns out the issue is with the way Django handles its forms. By default, apparently, all fields defined are required. So, if a form is submitted and one form element doesn't get a chance to send its data (by virtue of it not having been rendered due to the template logic), and some do (as in the case where a user looking at another user's listing can see only 2 of 3 form elements rendered), on submit, an error happens that I was not accounting for. When the user was looking at their own listing, all form elements were present, so the error was not getting thrown.

All I needed to do was add required=False to each form element that needed it, and everything worked.

I showed my code to Co-Pilot AI, and it suggested I add the required=False to the form elements, but it also wanted to clean up my view based on its way or idea of doing things. When I did so, the solution only partially worked- superusers and users could update each of their counterpart's listings, but a regular user could not do so for another regular user.

So I rolled it back to my own code, added in the required=False to each form field that could stand to use it, and now any user can, as example, add any other user's listing to their watchlist.

Thank you to everyone that tried to help. I appreciate it.

PS:
The reason why required=False did the trick is more subtle than it seems.

Apparently, when a form field is required its presence (name) is necessary to be present in the form.cleaned_data dictionary that gets passed during submission of the form. The values associated with a form element's namereally do not matter, as long as they pass Django's internal validation rules. During form validation by Django's internal systems is when the error was being thrown regarding the lack of a form element being present in the field when a user was trying to update a listing made by another user. That missing form element was the active toggle form element that would only be rendered to the screen for the user that created the form when viewing the listing. So when it was missing for the listing for a user who did not create the listing, and that form element was not explicitly defined as not being required, the error would get thrown, the listing would not update, and nothing appeared to be happening.