-
Notifications
You must be signed in to change notification settings - Fork 263
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
Functional changes to use the concrete job model where appropriate #1457
Conversation
…where appropriate
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 don't know how you do it, but another large body of work that requires little input. I just have a couple comments, but nothing deal-breaking!
def _get_detail_url(self, instance): | ||
""" | ||
Override default implementation as we're under "jobmodel-detail" rather than "job-detail". | ||
""" | ||
viewname = f"{self._get_view_namespace()}:jobmodel-detail" | ||
return reverse(viewname, kwargs={"pk": instance.pk}) | ||
|
||
def _get_list_url(self): | ||
""" | ||
Override default implementation as we're under "jobmodel-list" rather than "job-list". | ||
""" | ||
viewname = f"{self._get_view_namespace()}:jobmodel-list" | ||
return reverse(viewname) |
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.
These rout names just gave me pause. Are these non-standard URL route names going to break some asserted patterns with helpers/utilities/templatetags/etc. where the singular is expected to match the model name?
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.
Quite possibly, yes. The problem is that for the REST API, the job-*
URL patterns are already in use by the existing (JobClass-based) API views. I could rename those and reclaim those patterns for the new API views but I was concerned about the possibility of breaking plugins by doing so. Happy to discuss further.
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.
To be revisited as part of #1465 I think.
self.assertIn("schedule", response.data) | ||
self.assertIn("job_result", response.data) | ||
self.assertIsNone(response.data["schedule"]) | ||
# The urls in a NestedJobResultSerializer depends on the request context, which we don't have |
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.
Could you fake a request with django.test.RequestFactory
? This comment helps but it's not entirely clear why deleting the url
fields is necessary otherwise. (It's not a big deal, just more of a curiosity.)
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'll look into this. Thanks!
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 tried some various approaches using DRF's APIRequestFactory
but couldn't figure out the magic sauce to make it work - I kept getting 403 Forbidden responses even when explicitly using force_authenticate(request)
. Leaving this as-is for now.
Additional TODOs (opened #1479 for these)
|
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.
A few nit
s but looks good overall.
job_content_type = ContentType.objects.get(app_label="extras", model="job") | ||
|
||
schedule_data = input_serializer.data.get("schedule") | ||
# BUG TODO: it looks like by omitting "schedule" you can immediately run an approval_required job here... |
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.
If this is the case, worthwhile backporting the fix to this.
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.
Filed #1476 to investigate this and fix it if needed.
job_content_type, | ||
scheduled_job.user, |
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.
Should remove this as a bug fix to current release.
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.
Opened #1475 for this.
@@ -82,22 +92,30 @@ <h1>{{ job }}</h1> | |||
{% endif %} | |||
</div> | |||
<div class="pull-right"> | |||
<button type="submit" name="_run" id="id__run" class="btn btn-primary"{% if not perms.extras.run_job %} disabled="disabled"{% endif %}><i class="mdi mdi-play"></i> Run Job Now</button> | |||
<button type="submit" name="_run" id="id__run" class="btn btn-primary" | |||
{% if not perms.extras.run_job or not job_model.installed or not job_model.enabled or job_model.job_class is None %} |
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.
Maybe future enhancement:
can_i_run(user):
return bool, reasons
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.
For now I added a JobModel.runnable
property that just aliases (installed and enabled and job_class is not None)
as a step in the right direction.
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.
Perfect! Just corroborating the job_model
introspection would be better as a template variable than a string of conditions inside the template logic and that solves it concisely.
Relates-to: #1001
REST API changes:
/api/extras/job-models/
URL pattern; existing/api/extras/jobs/
should be considered deprecated/api/extras/job-models/<pk>/run
API endpoint accepts the same parameters as the existing job-running API endpoint, but instead of returning a serialized job-class instance (why?) now returns either a serialized JobResult or a serialized ScheduledJob depending on which action resulted from the request.api/extras/job-models/<pk>
returns a serialized JobModel, not a serialized JobClass, this endpoint does not return information about the parameters expected on job submission as that's a JobClass property. To fill this gap, I added anapi/extras/job-models/<pk>/variables
query endpoint which returns a detailed view into the job variables.JobResult
andScheduledJob
serializers/API endpoints now include a NestedJobSerializer representation of the associated JobModel.UI changes:
JobClass.as_form()
now derives itscommit_default
andread_only
properties from the JobModel rather than the JobClassjob.html
) derives itsname
,description
,read_only
andapproval_required
properties from the JobModel rather than the JobClass.installed
andenabled
.name
,description
,read_only
properties from the JobModel rather than the JobClassinstalled
andenabled
grouping
,name
, anddescription
from the JobModel if available (with a fallback to the JobClass available for now)Functional changes:
run_job
refuses to run if the associated JobModel is not bothinstalled
andenabled
.run_job
derives itssoft_time_limit
,time_limit
, andread_only
properties from the JobModel rather than the JobClassJobResult.enqueue_job
pulls thesoft_time_limit
andtime_limit
from the JobModel rather than the JobClass..get_for_class_path
convenience method to the JobModel manager.Database changes:
git_repository
foreign-key on JobModel, Jobs derived from a Git repository now havesource = "git"
and an appropriately set foreign-key, instead of the previous behavior ofsource = "git.{repository_slug}"
.clean
logic on JobModel to ensure that field length limits are enforced for the fields that are auto-populated from JobClass code.Testing changes:
test_api.py
are now also executed against the new JobModel run API./variables
API endpoint stilltest_jobs.py
to ensure that the JobModel isenabled
when performing various job-running tests.test_models.py
adds some tests on input validation when generating a JobModel.test_scripts.py
because inline declaration ofScript
(JobClass
) classes within a test case don't work so well when we need a JobModel associated with them.test_views.py
runs all of its tests against both the existing class-path-based URL patterns as well as the new slug-based URL patterns for jobs