Reputation: 4180
I'm currently having a bit of a conceptual headache over how best to reference the instance of a ForeignKey field inside a custom serializer validator method ...
To give an overview of the system. I have the following "Candidate
" model, the imporant fields for this question are the user
, job
* and status
fields.
from model_utils.fields import MonitorField, StatusField
from model_utils import Choices
class Candidate(models.Model):
class Meta:
...
STATUS = Choices(
'matched',
'approached',
'invite_rejected',
'invite_accepted',
'reviewed',
'interview_scheduled',
'hired',
'rejected'
)
user = models.ForeignKey('users.User', on_delete=models.CASCADE)
job = models.ForeignKey('jobs.Job', related_name='candidates', on_delete=models.CASCADE)
...
status = StatusField(default='matched')
...
def save(self, *args, **kwargs):
super(Candidate, self).save(*args, **kwargs)
The status
field for the Candidate
can only be "updated" to a given value based on who they are, and what they're attempting to update the status to. Effectively, my outlined logic is as follows inside the serializer:
from rest_framework import serializers
from .candidates.models import Candidate
class CandidateSerializer(serializers.ModelSerializer):
class Meta:
model = Candidate
fields = '__all__'
def validate_status(self, value):
user = self.context['request'].user
if user.is_anonymous:
raise serializers.ValidationError("The requester must be logged in to make a change to the status field")
# Ensure status value is in valid list of statuses
if value not in [
'matched',
'approached',
'invite_rejected',
'invite_accepted',
'reviewed',
'interview_scheduled',
'hired',
'rejected'
]:
raise serializers.ValidationError("The value provided does not match the prefedined status list")
# Only the candidate owner can update to certain statuses?
if value in [
'invite_rejected',
'invite_accepted',
]:
if not self.user == user:
raise serializers.ValidationError("You don't have the correct permission to update the status")
if value in [
'matched',
'approached',
'reviewed',
'interview_scheduled',
'hired',
'rejected'
]:
if user.is_anonymous or not self.job.organisation.is_admin(user) or not self.job.organisation.is_member(user):
raise serializers.ValidationError("You don't have the correct permission to update the status")
return value
That is to say, I can obtain the "user
" doing the updating or creation of the Candidate
model through the API from the serializer's self.context['request'].user
.
I'm also checking that this user
is at first, not anonymous.
What I want access to is the job
field for the above serializer.
I'm thinking the "job
" attribute for the serializer ... is accessible via self.job
.
However, I'm thinking that this is going to return the primary key of the Job
instance.
So...I wouldn't have access to the organisation
attribue on the self.job field, because it is not technically an instance of the Job
model:
user = self.context['request'].user
...
if not self.job.organisation.is_admin(user) or not self.job.organisation.is_member(user):
raise serializers.ValidationError("You don't have the correct permission to update the status")
So, my question is, how should I correctly reference the Job
instance associated to the Candidate
I'm trying to reference?
*N.B. It's worth noting that the "job
" field itself references a "Job
" model, and this Job model in turn has a field of organisation which links to an organisation as outlined in the django-organizations
package (reference here: https://github.com/bennylope/django-organizations/ if needed)
Upvotes: 0
Views: 101
Reputation: 3
Try something like this:
candidate = Candidate.objects.get(id=instance.pk)
job = Jobs.objects.filter(candidates__pk=candidate.pk)
You need to retrieve the job instance from a query, then you can use it as you want. For more complex things you can look at get_serializer_context(self)
then you can pass attributes to the serializers as kwargs..
Difficult to say more without viewing the whole stuff and the view
Upvotes: 0