Open StanGirard opened 3 years ago
I've looked into old issues to try to find an answer. I've compiled an answer but now I get a 404 on my route when I add this change: I've added the Mixins Organization and MembershipRequired and changed the get_queryset method.
Not Found: /api/extractor/
[21/Dec/2020 12:49:06] "GET /api/extractor/?ordering=id&page=1&page_size=10 HTTP/1.1" 404 1797
from extractor.models import Extractor
from rest_framework import viewsets
from rest_framework import filters
from rest_framework import permissions
from django_filters.rest_framework import DjangoFilterBackend
from extractor.serializers import ExtractorSerializer
from rest_framework import permissions
from org.models import Website
from organizations.views.mixins import MembershipRequiredMixin, OrganizationMixin
class ExtractorViewSet(MembershipRequiredMixin, OrganizationMixin,viewsets.ModelViewSet):
permission_classes = [permissions.IsAuthenticated]
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = Extractor.objects.order_by('-begin_date')
serializer_class = ExtractorSerializer
filter_backends = [DjangoFilterBackend,filters.OrderingFilter]
filterset_fields = ['type_audit', 'status_job']
ordering_fields = ['id', 'type_audit', 'begin_date']
def get_queryset(self):
return self.queryset.filter(org=self.get_organization())
I'm pretty sure there is something that I don't understand, and I'm probably a few lines of code away from the answer ๐
For people trying to integrate Django Organizations with Django Rest Framework (DRF) here is a working implementation of filtering results based on the user in the request.
from django.db import models
from organizations.models import Organization
# Create your models here.
class Website(Organization):
url = models.CharField(max_length=200)
I added a custom manager for the for_user
method
import datetime
from django.db import models
from django.utils import timezone
from org.models import Website
class ForUser(models.Manager):
def for_user(self, user):
org = Website.objects.filter(users=user)
return self.get_queryset().filter(org__in=org.values_list('id', flat=True))
class Extractor(models.Model):
Org = models.ForeignKey(Website, related_name='extractor', on_delete=models.CASCADE)
extractor_type = models.TextChoices('Extractor', 'HEADERS IMAGES LINKS')
url = models.CharField(max_length=200)
result = models.JSONField(blank=True, null=True)
type_audit = models.CharField(blank=True, choices=extractor_type.choices, max_length=20)
task_id = models.CharField(max_length=50, blank=True, null=True)
status_job = models.CharField(max_length=30, blank=True, null=True)
begin_date = models.DateTimeField(blank=True, null=True)
objects = ForUser()
def __repr__(self):
return '<Audit {}>'.format(self.url)
And then I overloaded the get_queryset method in my view.
from extractor.models import Extractor
from rest_framework import viewsets
from rest_framework import filters
from rest_framework import permissions
from django_filters.rest_framework import DjangoFilterBackend
from extractor.serializers import ExtractorSerializer
from rest_framework import permissions
from org.models import Website
class ExtractorViewSet(viewsets.ModelViewSet):
permission_classes = [permissions.IsAuthenticated]
"""
API endpoint that allows users to be viewed or edited.
"""
serializer_class = ExtractorSerializer
filter_backends = [DjangoFilterBackend,filters.OrderingFilter]
filterset_fields = ['type_audit', 'status_job']
ordering_fields = ['id', 'type_audit', 'begin_date']
def get_queryset(self):
return Extractor.objects.for_user(self.request.user).order_by('-begin_date')
I hope this will help somebody ๐ It isn't very hard but this was my first time using django.
Thanks @bennylope for this awesome project.
Please let me know if you have a better solution ๐
Hi @bennylope , is there any way to integrate this, sort of out of the box with DRF? As I'm pretty happy with the way this package handles everything already, and it'll be a bit of a hassle to "redo" most of the logic to integrate with DRF.
i think a way to go about this is to build a DRF layer that simple is annexed to the current code, meaning there's no need to change current code at all.
For example, one could (i'm already thinking in this direction), start with one view, say displaying one's groups after authentication, and create a DRF endpoint for that. One would likely need to extend the existing view for this functionality, run that view through a serializer, codify and endpoint, add in the DRF code... none of which seems hard, just a bit methodical and time-consuming. All the DEF endpoints could extend existing views and/or just re-use some of the view code in a DRF way.
I may try this, and will post back if it's bears fruit.
@marqpdx Seems like a good idea!
Any updates @marqpdx ?
ANSWER ON THIRD COMMENT
Hello guys,
Thanks a lot for this outstanding work.
I'm trying to integrate dj-organization into my DRF project and I'm having a bit of an issue. I'm struggling to filter the results the view sends back based on the user organization. I'm fairly new to Django and I'm having difficulties integrating it with DRF.
Here is my code.
My Organization
My Model which references the org
And my view for the Extractor Model
Extractor view
My question is as follow:
Where do I filter the Extractor object based on the user in the
request.user
so that he only sees the extractor for his organization ?I know this isn't an Issue as per say, but I'll be interested to add the answer in your documentation and an How To for others :)
Thanks a lot. Have a great day