django how to get request object (url param) in class based view - python

I have a class based view which has a query set like below:
def get_queryset(self):
queryset = Article.objects.all()
return queryset
If I pass an article id as a URL parameter like this:
<url>/stories/?articleid=1000
Then how can I get this value in the get_queryset function so that I can use it to filter? something like below:
def get_queryset(self):
articleId = #get the article_id from URL. How to do this?
queryset = Article.objects.filter(article_id=articleId)
return queryset
Any help is appreciated.

In this case, you can get it from self.request.GET["articleid'].
Note however this is not best practice in Django; you should write a URL pattern that includes the id directly, so that your URL would be /stories/100/.

Related

Add querystring parameters to from class based detail view with Django

How can I modify a class based view to add querystring parameters to the view? (So that when the view response is returned, the querystring is in the address bar?
class MyDetailView(DetailView):
"""
A detail view for retrieving a model object.
"""
model = MyModel
def some_function_to_modify_qs(self):
# do something and return modified qs for response
Not entirely sure why you’d want to do this, you could pass the values into the template instead but to answer your question the following should work.
from django.shortcuts import redirect
#inside your get method
return redirect(request.get_full_path() + “?query=string”)

unbound method get_queryset() must be called with WorkoutList instance as first argument (got nothing instead)

I am implementing DRF's Pagination over my existing web service (RESTful API). Now I learned from the docs of DRF Pagination that pagination is authomatically applied to ListCreateAPIView , only need to add some of the lines in settings.py file.
So I did the changes according to the documentation and for my webservice I wanted my queryset to be dynamic.
Below are the changes done:
urls.py
url(r'^users/(?P<pk>[0-9]+)/workouts/get/$',
ListCreateAPIView.as_view(WorkoutList.get_queryset(), serializer_class=WorkoutSerializer), name='list'),
views.py
class WorkoutList(generics.ListCreateAPIView):
queryset = Workout.objects.all()
serializer_class = WorkoutSerializer
permission_classes = (UserPermissions,)
def get_queryset(self):
workout_instance = WorkoutList()
workout_instance.get_queryset()
query_params = self.request.QUERY_PARAMS.dict()
if 'date' in query_params and 'exclude_app_install_time' in query_params:
query_set = Workout.objects.filter(created__contains=date).exclude(
app_install_time=query_params['exclude_app_install_time'])
else:
query_set = {}
return query_set
def list(self, request, *args, **kwargs):
workouts = self.get_queryset()
serializer = WorkoutSerializer(workouts, many=True)
return Response(serializer.data)
PS : I have stackoverflowed (pun intented) the problem but couldn't find the right solution(s).
Also I want to implement OffsetLimitPagination in the DRF. A small example link will be helpful
You're doing a couple of very strange things here.
If you subclass a view, you should use that subclass in the urls, not a strange mash-up of the original class and a method from the subclass. So:
url(r'^users/(?P<pk>[0-9]+)/workouts/get/$',
WorkoutList.as_view(serializer_class=WorkoutSerializer), name='list'),
Once you've fixed that, you'll get into an infinite recursion inside your get_queryset method. Again, when you subclass, if you want to call the original implementation you use super; you don't initialize another instance of the current class and try to call that method, because it'll be the same method.
def get_queryset(self):
query_set = super(WorkoutList, self).get_queryset()
Edit I guess the pagination doesn't work because you are starting from a blank Workout query rather than using the returned value from the super call. So you should do:
def get_queryset(self):
query_set = super(WorkoutList, self).get_queryset()
query_params = self.request.QUERY_PARAMS.dict()
if 'date' in query_params and 'exclude_app_install_time' in query_params:
query_set = query_set.filter(created__contains=date).exclude(
app_install_time=query_params['exclude_app_install_time'])
return query_set

How to return multiple queryset object or add queryset result from get_queryset method in Django

In my django application i have defined a ViewSet which has a get_queryset method as this :
class SampleViewSet(ReadOnlyModelViewSet):
serializer_class = SampleSerializer
permission_classes = (IsAuthorizedToAccess, )
def get_queryset(self):
queryset = Sample.objects.filter(submitted_by=self.request.user.id)
queryset1 = Sample.objects.filter(submitted_by!=self.request.user.id)
return queryset
This way i have two queryset objects 1st where samples are submitted by the user and 2nd where samples which are submitted by other users.
This SampleViewSet is called from an ajax request where i use the returned queryset object.
Can you please help how can i return both the objects.
For what i tried is i print the queryset object and tried fooling django by creating json object similar to the queryset.But it seems like django is quite intelligent in catching that.
EDIT: The question is should i look for an alternate method of get_queryset like list() [From Django Rest framework ] and return the json with Httpresponse or is there a real solution to either club two queryset object and return from here.
Until the author hasn't refined the question, the first guess is:
from itertools import chain
def get_queryset(self):
queryset = Sample.objects.filter(submitted_by=self.request.user.id)
queryset1 = Sample.objects.filter(submitted_by!=self.request.user.id)
return chain(queryset, queryset1)
without chain you can manage like this:
def list(self, request):
client = Client.objects.all()
server = Server.objects.all()
serializer1 = self.serializer_class(server, many=True)
serializer2 = self.serializer_class(client, many=True)
Serializer_list = [serializer1.data, serializer2.data]
return Response(Serializer_list)

Django: how to inject data when overriding get_queryset()?

Very begginer with the Django class based view.
I had a ListView that worked well but displayed all the objects. I wanted to filter this, and here what I did, following some examples found:
models.py:
class FolderElement(TimeStampedModel):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
class FolderMedia(TimeStampedModel):
folder_element = models.ForeignKey(FolderElement)
file = models.FileField(upload_to=generate_filepath_folder)
slug = models.SlugField(max_length=50, blank=True)
views.py:
class FolderMediaListView(ListView):
model = FolderMedia
template_name = "book.html"
def get_queryset(self):
self.folder_element = get_object_or_404(FolderElement,
pk=self.kwargs['pk'])
return FolderMedia.filter(folder_element=self.folder_element)
def render_to_response(self, context, **response_kwargs):
files = [ serialize(p) for p in self.get_queryset() ]
data = {'files': files}
response = JSONResponse(data, mimetype=response_mimetype(self.request))
response['Content-Disposition'] = 'inline; filename=files.json'
return response
But now that I overrided the get_queryset() method, I don't understand how I'm supposed to inject the pkparameter to the view sothat the filter works. Currently, using pdb, I can see that self.kwargs equals {} into the get_queryset() method.
Thanks.
The keyword arguments (kwargs) that the Django URL dispatcher passes to the view comes from the following:
Captured parameters in the URL expression
Additional arguments specified in the URL definition
All of them in urls.py.
So, for example, in order to get an ID form the URL in a form: /folder/id/:
url(r'folder/(?P<pk>\d+)/', FolderMediaListView.as_view)
Or if the id is constant (more rarely), you can pass it as an additional argument:
url(r'folder/', FolderMediaListView.as_view, {'pk': 1})
More information on the subject in the Django documentation.
You need to supply it in the URL. For example:
url(r'folder/(?P<id>\d+)/media', FolderMediaListView.as_view, name='folder_media_list')

Django REST framework filtering views

I managed to get data from the tables MemberDeclareRecept and Member with the following config files. Here I am looking for the MemberDeclareRecept.pk. But how can I get all the data if I search the Member.CoId instead?
The MemberSearchByCode view gives all the members in the table but I can't get the specific member.
Here are my models
class Member(models.Model):
Name = models.CharField(max_length=40,null=True)
FirstName = models.CharField(max_length=40,null=True)
DateBirth = models.DateField(,null=True)
CoId = models.CharField(max_length=6,null=True)
class MemberDeclareRecept(models.Model):
SyMember=models.ForeignKey(Member,verbose_name='Name member ',null=True,related_name='Member')
DateDeclareRecept=models.DateField(('Date received',null=True)
And the serializers that are being used
class MemberDeclareSerializer(serializers.ModelSerializer):
member = serializers.StringRelatedField(read_only=True)
SyRecept=serializers.StringRelatedField(read_only=True)
class Meta:
model = MemberDeclareRecept
fields=('id','member','SyRecept')
And the views that I am currently using
class MemberDeclareDetail(generics.ListCreateAPIView):
queryset=MemberDeclareRecep.objects.all()
serializer_class =MemberDeclareSerializer
def get_object(self,pk):
try:
return self.queryset.get(pk=pk)
except MemberDeclareRecep.DoesNotExist:
raise Http404
def get(self, request, pk,format=None):
entries = self.get_object(pk)
serializer = MemberDeclareSerializer(entries)
return Response(serializer.data)
class MemberSearchByCode(generics.ListAPIView):
serializer_class =MemberSerializer
def get_queryset(self):
member=self.request.QUERY_PARAMS.get(Co_id',None)
if membre is not None:
queryset = queryset.filter(member__Name=member
return queryset
It appears as though you've found an answer, based on the comment, and it's included below.
class MemberSearch(generics.ListAPIView):
serializer_class=MemberDeclareSerializer
def get_queryset(self):
member = self.kwargs['Co_id']
return member_declare_recept.objects.filter(member__Co_id=member)
It is important to note that this is not filtering the queryset based on query parameters, this is filtering it based on parameters present in the url. If you were filtering it based on query parameters, which is useful if you will need to get a list of all objects at once, the url that you would be using would be like
/api/members/?company=[co_id]
Which would make the company id optional. In your case though, the id is being embedded within the url itself. This is typically referred to as hierarchal urls, and it's generally not recommended, but your urls end up like
/api/company/[co_id]/members
Which is preferable for some, and even required in certain cases.
Now, if you wanted to use the query parameter instead of the url parameter for filtering, only a slight change would be required in your code.
class MemberSearch(generics.ListAPIView):
serializer_class=MemberDeclareSerializer
def get_queryset(self):
company_id = self.request.query_parameters.get('company', None)
if not company_id:
return member_declare_recept.objects.all()
return member_declare_recept.objects.filter(member__Co_id=company_id)
This has the additional advantage of also being support directly through django-filter and the DjangoFilterBackend.

Categories

Resources