17👍
Based in your comment, you could send the ids via url:
127.0.0.1:8000/snippets/?ids=2,3,4
and in your view
...
ids = request.GET.get('ids') # u'2,3,4' <- this is unicode
ids = ids.split(',') # [u'2',u'3',u'4'] <- this is a list of unicodes with ids values
Then you can query to Snippet model:
Snippet.objects.filter(pk__in=ids)
This could give you some problems if there’s spaces between ids in url:
127.0.0.1:8000/snippets/?ids=2, 3 , 4
You could need process every value before perform a query
11👍
I found this to work, following the Django REST Framework main tutorial and then documentation on Filtering against query parameters, adapting slightly. This allows a single url to return data from two GET requests: one returning objects whose ids match those given as a parameter, the other returning all objects, when no parameters are provided.
- http://127.0.0.1:8000/snippets/ returns all snippets
- http://127.0.0.1:8000/snippets/?ids=2,3,7 returns only snippets with id 2, 3 and 7
snippets/urls.py
from django.conf.urls import url
from snippets import views
urlpatterns = [
.... (code for other urls here)
url(r'^snippets/$', views.SnippetList.as_view(), name='snippet-list'),
....
]
snippets/views.py
....
from snippet.serializers import SnippetSerializer
....
class SnippetList(generics.ListCreateAPIView):
serializer_class = SnippetSerializer
def get_queryset(self):
# Get URL parameter as a string, if exists
ids = self.request.query_params.get('ids', None)
# Get snippets for ids if they exist
if ids is not None:
# Convert parameter string to list of integers
ids = [ int(x) for x in ids.split(',') ]
# Get objects for all parameter ids
queryset = Product.objects.filter(pk__in=ids)
else:
# Else no parameters, return all objects
queryset = Product.objects.all()
return queryset
snippets/serializers.py
....
class SnippetSerializer(serializers.ModelSerializer):
class Meta:
model = Snippet
fields = ('url', 'id', 'title', 'code', 'linenos', 'language', 'style')
- How to pass in a starting sequence number to a Django factory_boy factory?
- Pass a query parameter with django reverse?
- "Error: That IP address can't be assigned-to" when running app
7👍
You can use django-filter and set it up as a filter and avoid over riding the get_queryset method on the viewset
Given this request
/api/snippets/?ids=1,2,3,4
Then write a django filter set and method
import django_filters
def filter_by_ids(queryset, name, value):
values = value.split(',')
return queryset.filter(id__in=values)
class SnippetFilterSet(django_filters.FilterSet):
ids = django_filters.CharFilter(method=filter_by_ids)
class Meta:
model = Snippet
fields = ['ids']
And then in your ModelViewSet
from rest_framework.viewsets import ModelViewSet
from app.snippets.models import Snippet
from app.snippets.filters import SnippetFilterSet # path to filterset
class SnippetView(ModelViewSet):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
filterset_class = SnippetFilterSet
- How to use Datepicker in django
- DJango: formatting json serialization
- Django REST framework: Can a nested object access its parent object's details in a List View?
3👍
A possible way is to send the lis of pk(s) as GET request data, somthing like this:
-
GET request to “/snippets”
-
Request body: {“list_of_pk”: [1,2,3…]}
And then:
snippets/urls.py
from django.conf.urls import url
from snippets import views
urlpatterns = [
url(r'^snippets/$', views.snippet_list),
url(r'^snippets/(?P<pk>[0-9]+)/$', views.snippet_detail),
]
snippets/views.py
def snippet_list(request):
if request.method == 'GET':
pk_list = request.GET.get('list_of_pk')
if pk_list:
snippets = Snippet.objects.filter(pk__in=pk_list)
else:
snippets = Snippet.objects.all()
#the serialization...
- ( django.core.exceptions.ImproperlyConfigured: Cannot import 'apps.accounts'. Check that 'mysite.apps.accounts.apps.AccountsConfig.name' is correct
- Annotate QuerySet with first value of ordered related model
- How to compare version string ("x.y.z") in MySQL?
- How to make a field editable on create and read-only on update in Django REST framework
- Inlineformset_factory create new objects and edit objects after created
3👍
Here’s what I ended up going with:
No changes to
snippet/urls.py
from django.conf.urls import url
from snippets import views
urlpatterns = [
url(r'^snippets/$', views.snippet_list),
url(r'^snippets/(?P<pk>[0-9]+)/$', views.snippet_detail),
]
http://127.0.0.1:8000/snippets/?ids=2,3,4 is received by
snippet/views.py
from rest_framework.decorators import api_view
@api_view(['GET', 'POST'])
def snippet_list(request):
if request.method == 'GET':
ids = request.query_params.get('ids') # u'2,3,4' <- this is unicode
ids = ids.split(',')
snippets = Snippet.objects.filter(pk__in=ids)
serializer = SnippetSerializer(snippet, many=True)
return JSONResponse(serializer.data)
0👍
While there is no definitive standard, most web frameworks allow multiple values to be associated with a single field (e.g. field1=value1&field1=value2&field2=value3).
Django also supports this.
To get list of values you can use: ids = request.GET.getlist('ids')
.
More examples from MultiValueDict
docs:
>>> d = MultiValueDict({'name': ['Adrian', 'Simon'], 'position': ['Developer']})
>>> d['name']
'Simon'
>>> d.getlist('name')
['Adrian', 'Simon']
>>> d.getlist('doesnotexist')
[]
>>> d.getlist('doesnotexist', ['Adrian', 'Simon'])
['Adrian', 'Simon']
>>> d.get('lastname', 'nonexistent')
'nonexistent'
>>> d.setlist('lastname', ['Holovaty', 'Willison'])
0👍
The django-filter documentation give a good example how to do it: https://django-filter.readthedocs.io/en/stable/ref/filters.html?highlight=ids#baseinfilter
For your case:
class SnippetFilterSet(BaseInFilter, NumberFilter):
pass
class F(FilterSet):
ids = NumberInFilter(field_name='id', lookup_expr='in')
class Meta:
model = Snippet
- Took too long to shut down and was killed
- How do I get django runserver to show me DeprecationWarnings and other useful messages?
- How to use select_related with GenericForeignKey in django?
- Setting default value for integer field in django models