review request model

This commit is contained in:
rmanyari 2023-03-10 16:02:05 -07:00
parent 1f70360592
commit 59c99ddbfe
5 changed files with 98 additions and 3 deletions

View File

@ -11,7 +11,7 @@ from dcim.api.nested_serializers import (
from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup
from extras.choices import * from extras.choices import *
from extras.models import * from extras.models import *
from extras.models.staging import Notification from extras.models.staging import Notification, ReviewRequest
from extras.utils import FeatureQuery from extras.utils import FeatureQuery
from netbox.api.exceptions import SerializerNotFound from netbox.api.exceptions import SerializerNotFound
from netbox.api.fields import ChoiceField, ContentTypeField, SerializedPKRelatedField from netbox.api.fields import ChoiceField, ContentTypeField, SerializedPKRelatedField
@ -537,3 +537,16 @@ class NotificationSerializer(BaseModelSerializer):
fields = [ fields = [
'id', 'url', 'created', 'title', 'content', 'read' 'id', 'url', 'created', 'title', 'content', 'read'
] ]
class ReviewRequestSerializer(BaseModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='extras-api:review-requests-detail')
def create(self, validated_data):
pass
class Meta:
model = ReviewRequest
fields = [
'id', 'url', 'created', 'last_updated', 'owner', 'reviewer', 'branch', 'status', 'state'
]

View File

@ -20,6 +20,7 @@ router.register('object-changes', views.ObjectChangeViewSet)
router.register('job-results', views.JobResultViewSet) router.register('job-results', views.JobResultViewSet)
router.register('content-types', views.ContentTypeViewSet) router.register('content-types', views.ContentTypeViewSet)
router.register('notifications', views.NotificationViewSet, basename='notifications') router.register('notifications', views.NotificationViewSet, basename='notifications')
router.register('review-requests', views.ReviewRequestViewSet, basename='review-requests')
app_name = 'extras-api' app_name = 'extras-api'
urlpatterns = router.urls urlpatterns = router.urls

View File

@ -15,7 +15,7 @@ from extras import filtersets
from extras.choices import JobResultStatusChoices from extras.choices import JobResultStatusChoices
from extras.models import * from extras.models import *
from extras.models import CustomField from extras.models import CustomField
from extras.models.staging import Notification from extras.models.staging import Notification, ReviewRequest
from extras.reports import get_report, get_reports, run_report from extras.reports import get_report, get_reports, run_report
from extras.scripts import get_script, get_scripts, run_script from extras.scripts import get_script, get_scripts, run_script
from netbox.api.authentication import IsAuthenticatedOrLoginNotRequired from netbox.api.authentication import IsAuthenticatedOrLoginNotRequired
@ -406,6 +406,7 @@ class NotificationViewSet(ReadOnlyModelViewSet):
serializer_class = serializers.NotificationSerializer serializer_class = serializers.NotificationSerializer
def get_queryset(self): def get_queryset(self):
# TODO: Maybe we want to drop the filter if an admin is querying.
return Notification.objects.filter(user__id=self.request.user.id).order_by('created') return Notification.objects.filter(user__id=self.request.user.id).order_by('created')
def partial_update(self, request, pk=None): def partial_update(self, request, pk=None):
@ -419,3 +420,15 @@ class NotificationViewSet(ReadOnlyModelViewSet):
n = get_object_or_404(self.get_queryset(), pk=pk) n = get_object_or_404(self.get_queryset(), pk=pk)
n.delete() n.delete()
return Response(status=status.HTTP_200_OK) return Response(status=status.HTTP_200_OK)
class ReviewRequestViewSet(ReadOnlyModelViewSet):
permission_classes = [IsAuthenticatedOrLoginNotRequired]
serializer_class = serializers.ReviewRequestSerializer
def get_queryset(self):
return ReviewRequest.objects.filter(owner__id=self.request.user.id).order_by('last_updated')
def create(self, create):
pass

View File

@ -199,3 +199,27 @@ class ChangeActionChoices(ChoiceSet):
(ACTION_UPDATE, 'Update'), (ACTION_UPDATE, 'Update'),
(ACTION_DELETE, 'Delete'), (ACTION_DELETE, 'Delete'),
) )
class ReviewRequestStateChoices(ChoiceSet):
STATE_UNDER_REVIEW = 'under_review'
STATE_APPROVED = 'approved'
STATE_DENIED = 'denied'
CHOICES = (
(STATE_UNDER_REVIEW, 'Under Review'),
(STATE_APPROVED, 'Approved'),
(STATE_DENIED, 'Denied')
)
class ReviewRequestStatusChoices(ChoiceSet):
STATUS_OPEN = 'open'
STATUS_CLOSED = 'closed'
CHOICES = (
(STATUS_OPEN, 'Open'),
(STATUS_CLOSED, 'Closed')
)

View File

@ -7,7 +7,9 @@ from django.db import models, transaction
from django.conf import settings from django.conf import settings
from django.urls import reverse from django.urls import reverse
from extras.choices import ChangeActionChoices from extras.choices import ChangeActionChoices, \
ReviewRequestStateChoices, \
ReviewRequestStatusChoices
from netbox.models import ChangeLoggedModel, NetBoxModel from netbox.models import ChangeLoggedModel, NetBoxModel
from utilities.utils import deserialize_object from utilities.utils import deserialize_object
@ -147,3 +149,45 @@ class Notification(NetBoxModel):
class Meta: class Meta:
ordering = ('pk',) ordering = ('pk',)
class ReviewRequest(ChangeLoggedModel):
owner = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='review_requests'
)
reviewer = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='assigned_review_requests'
)
branch = models.ForeignKey(
to=Branch,
on_delete=models.CASCADE,
related_name='review_request'
)
status = models.CharField(
max_length=256,
choices=ReviewRequestStatusChoices,
default=ReviewRequestStatusChoices.STATUS_OPEN
)
state = models.CharField(
max_length=256,
choices=ReviewRequestStateChoices,
default=ReviewRequestStateChoices.STATE_UNDER_REVIEW
)
def __str__(self):
return f'[OwnerId: {self.owner.pk}, ReviewerId: {self.reviewer.id} {self.status}/{self.state}] {self.branch}'
def get_absolute_url(self):
return reverse('extras-api:review-requests-detail', args=[self.pk])
class Meta:
ordering = ('pk',)