In ModelSerializer self.context doesn't have request , how to get this - django

my serialiser class is:
class NakshatraDateSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(read_only=True)
is_note_present = serializers.SerializerMethodField(read_only=True)
def get_is_note_present(self, nakshatra_date ):
user = None
request = self.context.get("request")
print (str(request))
if request and hasattr(request, "user"):
user = request.user
# user = serializers.SerializerMethodField('_user')
if user is None:
logging.error("user is none")
return False
try:
nakshatra_date_note = Notes.objects.all().get(nakshatra_date=nakshatra_date, created_by=user)
except ObjectDoesNotExist:
nakshatra_date_note = None
if nakshatra_date_note is None:
logging.error("no note present for this nakshatra date")
return False
logging.error(str(nakshatra_date_note))
return True
date = serializers.DateField(
required=True,
error_messages={
"date": "Nakshatra for date already present",
},
validators=[UniqueValidator(queryset=NakshatraDate.objects.all(), message="Nakshatra for date already present
")]
)
class Meta:
model = NakshatraDate
fields = (
'id', 'is_note_present', 'date', 'updated', 'created')
vewclass is :
class NakshatraDateViewSet(viewsets.ModelViewSet):
"""
Nakshatra dates
"""
permission_classes = (AllowAny,)
queryset = NakshatraDate.objects.all()
serializer_class = NakshatraDateSerializer
pagination_class = LargeResultsSetPagination
filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
filter_class = NakshatraDateFilter
def filter_queryset(self, queryset):
queryset = super(NakshatraDateViewSet, self).filter_queryset(queryset)
return queryset.order_by('-id')
def perform_create(self, serializer):
serializer.save()
i am trying to set value 'True' in variable is_note_present if a Note is present on a particular date. or else 'False'. But i am not able to get request object in self.context.
class Notes(models.Model):
date = models.DateField(null=False)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True, editable=False)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='notes', on_delete=models.CASCADE)
i tried various way to get request . some of them aredef get_serializer_context(self):
return {'request': self.request}
and trien to context (context={'request':request}) with serialize_class variable in modelviewset
still i am not able to get the request in self.context

Your view should be like this.
class NakshatraDateViewSet(viewsets.ModelViewSet):
"""
Nakshatra dates
"""
permission_classes = (AllowAny,)
serializer_class = NakshatraDateSerializer
pagination_class = LargeResultsSetPagination
filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
filter_class = NakshatraDateFilter
def get_queryset(self, queryset):
queryset = NakshatraDate.objects.all()
return queryset.order_by('-id')
def get_serializer_context(self):
return {'request': self.request}
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(data=serializer.data)
return Response(status=status.HTTP_400_BAD_REQUEST)
You can see further about viewsets here.

Related

Check if object parent user == request.user on child object create/update

I want to check if parent object user is request.user to correctly add child amd grandchild object permissions.
Wanna figure out how to do it properly in Django & DRF.
Models:
class Parent(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
class Child(models.Model):
parent = models.ForeignKey(Parent, on_delete=models.CASCADE, related_name='childs')
class SecondChild(models.Model):
parent = models.ForeignKey(Child, on_delete=models.CASCADE, related_name='secondchilds')
Views:
class ParentViewSet(viewsets.ModelViewSet):
queryset = Parent.objects.all()
serializer_class = ParentSerializer
permission_classes = [permissions.IsAuthenticated, IsOwner]
def perform_create(self, serializer):
serializer.save(user=self.request.user)
def get_queryset(self):
user = self.request.user
if user.is_superuser:
return Parent.objects.all()
return Parent.objects.filter(user=user).prefetch_related('childs', 'childs__secondchilds')
class ChildViewSet(viewsets.ModelViewSet):
queryset = Child.objects.all()
serializer_class = ChildSerializer
permission_classes = [permissions.IsAuthenticated]
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
parent_id = self.request.data.get('parent_id')
parent_instance = Parent.objects.filter(id=parent_id).first()
if not serializer.is_valid(raise_exception=True):
print(serializer.errors)
serializer.save(parent=parent_instance)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def get_queryset(self):
user = self.request.user
if user.is_superuser:
return Parent.objects.all()
return Child.objects.filter(parent__user=user).prefetch_related('SecondChild')
you can do the checking on your custom permission class, then add the it to your view's permission_classes list
permissions
class IsParentOwnerOrReadOnly(permissions.BasePermission):
def has_permission(self, request, view):
parent_id = int(request.data.get('parent_id'))
parent_instance = Parent.objects.filter(id=parent_id).first()
return (request.method in permissions.SAFE_METHODS or
(parent_instance and request.user == parent_instance.user))
views
class ChildViewSet(viewsets.ModelViewSet):
...
permission_classes = [permissions.IsAuthenticated, IsParentOwnerOrReadOnly]
...

self.request.user does not work in Django REST framework

I want to give only the information of the user who requested with self.request.user, but for some reason, this way I get the information of all users.
How can I improve this so that we can retrieve only the information of the user who requested it?
Please let me know if you know anything about this.
View
class StatisticsViewSet(APIView):
permission_classes = [permissions.IsAuthenticated]
serializer_class = EntrySerializer
def get(self, request):
queryset = self.request.user.entries.all()
serializer = StatisticsSerializer(queryset)
return Response(serializer.data)
Serializer
class StatisticsSerializer(serializers.Serializer):
daily_report = serializers.SerializerMethodField()
daily_report_week = serializers.SerializerMethodField()
def get_daily_report(self, obj):
data = Entry.objects.filter(user=obj.user).values(
'created_at__year', 'created_at__month',
'created_at__day').annotate(Sum('time')).order_by(
'created_at__year', 'created_at__month', 'created_at__day')
........
...
...
Model
class Entry(models.Model):
project = models.ForeignKey(Project,
related_name='entries',
on_delete=models.CASCADE)
time = models.IntegerField(default=0)
user = models.ForeignKey(User,
related_name='entries',
on_delete=models.CASCADE)
created_at = models.DateTimeField(default=datetime.now)
def __str__(self):
return '%s - %s' % (self.project.name, self.created_at)
You can filter the queryset inside the serializer using the context
Serializer:
class StatisticsSerializer(serializers.Serializer):
daily_report = serializers.SerializerMethodField()
daily_report_week = serializers.SerializerMethodField()
def get_daily_report(self, obj):
user = self.context['request'].user
data = Entry.objects.filter(user=user).values(
'created_at__year', 'created_at__month',
'created_at__day').annotate(Sum('time')).order_by(
'created_at__year', 'created_at__month', 'created_at__day')
View:
class StatisticsViewSet(APIView):
permission_classes = [permissions.IsAuthenticated]
serializer_class = EntrySerializer
def get(self, request):
queryset = self.request.user.entries.all()
serializer = StatisticsSerializer(queryset, context = {'request': self.request)
return Response(serializer.data)

Django RF, validation of input data in view layer

I wanted to get the date or tablerequireDate argument from the POST requests, how do I achieve in the below view layer ?
VIEWS.PY
class Tablecreateview(generics.CreateAPIView):
queryset = Tables.objects.all()
serializer_class = Tableserializer
def perform_create(self, serializer):
request_user = self.request.user
serializer.save(author=request_user)
MODELS.PY
class Tables(models.Model):
tablerequiretime = models.TimeField()
tablerequireDate = models.DateField()
created = models.DateTimeField(auto_now=True)
updatedat = models.DateTimeField(auto_now_add=True)
foodliketoeat = models.CharField(max_length=200)
totalpersons = models.PositiveIntegerField(
default=0, validators=[MinValueValidator(0), MaxValueValidator(20)])
author = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
def __str__(self):
return self.author.username
SERIALIZERS.PY
class Tableserializer(serializers.ModelSerializer):
class Meta:
model = Tables
exclude=('author',)
Okay you can access this field before perform_create takes place
class Tablecreateview(generics.CreateAPIView):
queryset = Tables.objects.all()
serializer_class = Tableserializer
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
tablerequireDate = serializer.data['tablerequireDate']
# Do you magic then perform creation
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
Another Round of a solution
class Tableserializer(ModelSerializer):
class Meta:
model = Tables
exclude=('author',)
def validate_tablerequireDate(self, data):
try:
# do validation
except ValidationError:
raise Validation.....
else:
return validated_data

Call for model field validation in the serializer

I will try to make a check for the uniqueness of the field at the validation level in the serializer and can not understand why the validator is not called at all.
models.py
class Vendor(models.Model):
active = models.BooleanField(default=False)
...
class VendorContacts(models.Model):
vendor = models.ForeignKey('Vendors', related_name='contacts', on_delete=models.CASCADE)
email = models.CharField(max_length=80, blank=True, null=True)
.....
serializer.py
class VendorContactCreateSerializer(serializers.ModelSerializer):
email = serializers.CharField(validators=[RegexValidator(regex=r'[^#]+#[^\.]+\..+',
message='Enter valid email address')])
vendor = serializers.PrimaryKeyRelatedField(queryset=Vendors.objects.all(), required=False, allow_null=True)
class Meta:
model = VendorContacts
fields = (.....
)
def create(self, validated_data):
.....
#some logic
def validate_email(self, value):
print('Start validation')
exist_contact = VendorContacts.objects.filter(email=value)
if exist_contact:
vc = get_object_or_404(VendorContacts, email=value)
v = vc.vendor
if v.active:
raise serializers.ValidationError('Email {} already exists'.format(value))
return value
In the above serializer, I perform a check at the def validate_email() model field level.
print('Start validation') is not called.
I tried the same at the object level through def validate(): but it is not called either.
UPD
views.py
class VendorContactsCreateView(APIView):
permission_classes = [permissions.AllowAny, ]
serializer_class = VendorContactCreateSerializer
def post(self, request, *args, **kwargs):
data = request.data
serializer = VendorContactCreateSerializer(data=data)
try:
serializer.is_valid(raise_exception=True)
serializer.save()
except ValidationError:
return Response({"errors": (serializer.errors,)},
status=status.HTTP_400_BAD_REQUEST)
else:
return Response(request.data, status=status.HTTP_200_OK)

I want to get the list of all the employees that are registered with the company along with their designation

I am working on a model and I want to get the details of the employees in an organization along with their designations. I cannot think of anything at this point of time. This is my first time asking a question here so any help would mean a lot and if I havent provided the exact details please tell me. I think these should be sufficient enough for the answe.
Here is my organization and userorgdetail models:
class Organization(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=256)
employees = models.ManyToManyField(InSocialUser, related_name='organizations', blank=True,
through="UserOrgDetail")
description=models.TextField(blank=True)
class UserOrgDetail(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.ForeignKey(InSocialUser, related_name='org_details', on_delete=models.CASCADE)
org = models.ForeignKey(Organization, related_name='employee_details', on_delete=models.CASCADE)
designation = models.CharField(max_length=256)
REQUIRED_FIELDS = ['user','org']
Here is my serializers file:
class OrgSerializer(serializers.ModelSerializer):
class Meta:
model = Organization
fields = ('id','name','employees')
class UserOrgDetailSerializer(serializers.ModelSerializer):
class Meta:
model = UserOrgDetail
fields = '__all__'
class UserOrgDetailReadSerializer(UserOrgDetailSerializer):
user = serializers.PrimaryKeyRelatedField(read_only=True)
org = OrgSerializer(read_only=True)
views.py
class OrganizationAPIView(
mixins.CreateModelMixin,
generics.ListAPIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
serializer_class = OrgSerializer
filter_backends = [filters.OrderingFilter,filters.SearchFilter]
search_fields = ['name']
ordering_fields = ['name']
ordering = ['name']
queryset = Organization.objects.all()
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
def perform_create(self, serializer):
serializer.save()
class UserOrgDetailAPIView(
mixins.CreateModelMixin,
generics.ListAPIView):
permission_classes = [permissions.IsAuthenticated]
serializer_class = UserOrgDetailReadSerializer
filter_backends = [filters.OrderingFilter,filters.SearchFilter]
search_fields = ['designation']
ordering_fields = ['name']
ordering = ['name']
def get_queryset(self, *args, **kwargs):
id = self.kwargs.get("id",None)
"""
This view should return a list of all the Organization Details of the logged in user
"""
queryset = UserOrgDetail.objects.filter(user__id=id)
return queryset
def post(self, request, *args, **kwargs):
id = self.kwargs.get("id",None)
#user = get_object_or_404(User, id=id)
user = User.objects.get(id=id)
orgId = request.data.get('org_id')
org = Organization.objects.get(pk=orgId)
designation = request.data.get('designation')
org_detail = UserOrgDetail.objects.create(user=user,org=org,designation=designation)
user.save()
return Response({"status": "Success","result":UserOrgDetailReadSerializer(org_detail).data})
class UserOrgDetailDetailAPIView(
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
generics.RetrieveAPIView):
permission_classes = [permissions.IsAuthenticated]
serializer_class = UserOrgDetailReadSerializer
queryset = UserOrgDetail.objects.all()
lookup_field = 'id'
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def patch(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
def get_serializer_class(self):
if self.request.method == 'GET':
return UserOrgDetailReadSerializer
else:
return self.serializer_class
I want that when I fire the get request for userorgdetail I get the employees working in the company along with their designation. Any help would be very useful, Thank you