-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Usage requirements refactor #749
base: dev
Are you sure you want to change the base?
Conversation
Deployment
Hotfix deployment 🚑
Deployment
Deployment
Deployment
Hotfix deployment
Deployment
Always use the pull request template
Deployment
Deployment
Deployment
Deployment
Deployment
Deployment
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## dev #749 +/- ##
==========================================
+ Coverage 88.17% 88.27% +0.09%
==========================================
Files 152 152
Lines 6198 6198
==========================================
+ Hits 5465 5471 +6
+ Misses 733 727 -6
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you've changed all line endings from \n
(the Linux/Unix default) to \r\n
(the Windows default) 😅 The default Git setting on Windows is to convert all line endings to \n
when committing, and you can reset that setting to the default value by running git config --global core.autocrlf true
🙂 See the GitHub docs on line endings for more details.
Btw, do you want my review on your code? It will be detailed, but I won't do it to enforce some code standard on this repo; rather, I'll to try to teach conventions and good coding practices that will be useful in a programming career 🙂 No worries if you're not interested 😊 |
We need these changes as soon as possible for the new printers, but i'm still interested in the review for future improvement and learning. Thanks |
Worst case, it's always possible to just check out this branch on the server, if needed for whatever reason 🤠 But anyway: First, it would be great if you could convert the line endings, like I mentioned earlier, as the diff is pretty unreadable 😅 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other than my singular comment, I can't seem to find any bugs or issues when running the code locally and looking at all the things I think will be impacted by the changes.
Maybe have a look at the failing check by codeclimate for some code cleanup stuff while you are changing things, it seems to mostly be about too many or not enough blank lines and similar nitpick.
Well done with the PR!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Finally found some free time to review this 😅)
Very well done! 😄 I have some improvement suggestions below, but I'm impressed by your seemingly solid grasp of Django! 😊
CoursePermission = apps.get_model('make_queue', 'CoursePermission') | ||
|
||
CoursePermission.objects.bulk_create([ | ||
CoursePermission(name='User is authenticated', short_name='AUTH', description='Permission to reserve machines and workstations at MAKE NTNU'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can remove AUTH
entirely, as users are always required to be logged in when making a reservation anyway :)
def __str__(self): | ||
return self.name | ||
|
||
|
||
# `3DPrinterCourse` would be a syntactically invalid name :( | ||
class Printer3DCourse(models.Model): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this can be renamed to something like MachineCourse
, now that we have permissions for any machine type :)
src/checkin/views.py
Outdated
|
||
if completed_3d_printer: | ||
CoursePermission = user.printer_3d_course.course_permissions.model | ||
courses = CoursePermission.objects.exclude(short_name__in=["3DPR", "AUTH"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are quite a few hardcoded references to specific short_name
s in the code, so I think it would be a good idea to bring back a similar enum as the removed MachineType.UsageRequirement
, to avoid magic strings :)
Also:
courses = CoursePermission.objects.exclude(short_name__in=["3DPR", "AUTH"]) | |
special_courses = CoursePermission.objects.exclude(short_name__in=["3DPR", "AUTH"]) |
{% else %} | ||
{% translate "No" %} | ||
{% endif %} | ||
{% for name in registration.get_permission_names %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that the database will be queried every time get_permission_names()
is called in this loop, so to prevent that potentially massive N+1 problem, replace values_list()
with all()
in that method (as mentioned in a previous comment), and make Printer3DCourseListView.queryset
prefetch course_permissions
.
CoursePermission.objects.bulk_create([ | ||
CoursePermission(name='User is authenticated', short_name='AUTH', description='Permission to reserve machines and workstations at MAKE NTNU'), | ||
CoursePermission(name='3D printer course', short_name='3DPR', description='Permission to use 3D printers at MAKE NTNU'), | ||
CoursePermission(name='Raise3D course', short_name='R3DP', description='Permission to use the Raise3D printer at MAKE NTNU'), | ||
CoursePermission(name='SLA course', short_name='SLAP', description='Permission to use the SLA printer at MAKE NTNU'), | ||
]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do this when the 0035_coursepermission_printer3dcourse_course_permissions_and_more.py
migration already creates these objects? :p
@@ -320,7 +320,7 @@ def test_only_internal_users_can_view_internal_machines(self): | |||
response = self.client.get(machine_detail_url) | |||
expected_status_code = HTTPStatus.OK | |||
# ...except if the machine requires the SLA course | |||
if machine_type.usage_requirement == MachineType.UsageRequirement.TAKEN_SLA_3D_PRINTER_COURSE: | |||
if machine_type.usage_requirement.id == CoursePermission.objects.get(short_name='SLAP').id: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer using pk
instead of id
when you're only interested in getting the field that identifies the object (i.e. the primary key), instead of the field name itself :)
if machine_type.usage_requirement.id == CoursePermission.objects.get(short_name='SLAP').id: | |
if machine_type.usage_requirement.pk == CoursePermission.objects.get(short_name='SLAP').pk: |
@@ -6,15 +6,15 @@ A summary of changes made to the codebase, grouped per deployment. | |||
|
|||
### New features | |||
|
|||
- | |||
- You can now add more permission types that can be used by machine types and courses using the CoursePermission class. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think something like this is easier to understand for people who are unfamiliar with the code: (feel free to edit :))
- You can now add more permission types that can be used by machine types and courses using the CoursePermission class. | |
- Made it easier to add new permissions for any machine type, so that each permission can be granted when registering a | |
completed course |
@@ -8,6 +8,16 @@ | |||
from .fields import UsernameField | |||
|
|||
|
|||
class CoursePermission(models.Model): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lastly, on the topic of refactoring (or, since we are changing the functionality of the code, something like "Usage requirements rework" would probably be a more accurate PR title), do we need this model at all? We should be able to just remove it entirely and instead let Printer3DCourse.course_permissions
be an M2M field to MachineType
(and rename the field to something like for_machine_types
- as in "course for these machine types"), as all the existing usage requirements are tied to a specific machine type (except AUTH
, which I commented on above) 🤔 For the machines without usage requirement (i.e. sewing machines, etc.), we can just always allow access.
That refactor should probably be made in another PR, though, but do you have any thoughts on making that change? 🙂
(Refactoring one step further could be to remove the MachineType
model entirely and replace it with a hardcoded enum, as the PKs of that model are already hardcoded multiple places, and it's much easier to handle that with an enum instead of all the extra work of ensuring that certain MachineType
objects always exist in the database and always have the same PKs. Also, we don't really add or remove the machine types often enough to warrant having it as a model, in my opinion, and adding a new enum member is usually a tiny and quick change to make to the code, while keeping the advantages mentioned earlier. But making that change is definitely for another PR :))
Btw, it looks like you based this branch on But we should definitely squash-merge the PR, unless you're planning on cleaning up the commit history before merging. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work! 👍 I don't have a lot of comments regarding this PR. But when I was reviewing, I realized that this would have been a much easier job if there were more comments in the code, so I would like to request some comments / explanations in the code. The make_queue app contains maybe the most difficult code on the entire page, so especially when we make changes to this app, we should make an effort to make this part of the page more understandable for future members of the dev committee.
A more thorough description of the PR could also have been helpful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some problems with course registrations, both with the form itself, and with the behaviour of the init method on the Printer3DCourseForm. These have been there before, so they were not introduced by this PR, but they should nonetheless be fixed since we are changing this part of the page anyway.
First of all - it makes very little sense to have fields for both username and user, especially since it is actually possible to enter different user names in these two fields. The 'username' field is coupled to the 'full name' field, while the 'user' field suggests users from the User model while typing. This is a nice feature that should be kept in order to minimize the change for typos when entering usernames. Therefore, I would suggest removing the 'username' field, and auto-filling the 'full name' field from the 'user' field instead.
Also - if a user is already added to the User model with an EM number, the EM number will be erased from the User model when the same user is added to the Printer3DCourse model without an EM number. It is possible that the EM number will be restored by information received from Feide, but new instances to the Printer3DCourse model should still not be able to delete information from the User model, so this is obviously a bug, and it should be fixed. If an EM number is already present for the user that is being added to the Printer3DCourse model - it should instead be auto-filled in the EM number field, like the user's full name is in the 'full name' field.
Proposed changes
Machine types and courses use a new permission class instead of boolean for usage requirements
Areas to review closely
Checklist
(If any of the points are not relevant, mark them as checked)
makemigrations
,makemessages
andcompilemessages
management commands and committed any changes that should be included in this PR