Dynamically limiting queryset of related field

2024/11/20 19:40:08

Using Django REST Framework, I want to limit which values can be used in a related field in a creation.

For example consider this example (based on the filtering example on https://web.archive.org/web/20140515203013/http://www.django-rest-framework.org/api-guide/filtering.html, but changed to ListCreateAPIView):

class PurchaseList(generics.ListCreateAPIView)model = Purchaseserializer_class = PurchaseSerializerdef get_queryset(self):user = self.request.userreturn Purchase.objects.filter(purchaser=user)

In this example, how do I ensure that on creation the purchaser may only be equal to self.request.user, and that this is the only value populated in the dropdown in the form in the browsable API renderer?

Answer

I ended up doing something similar to what Khamaileon suggested here. Basically I modified my serializer to peek into the request, which kind of smells wrong, but it gets the job done... Here's how it looks (examplified with the purchase-example):

class PurchaseSerializer(serializers.HyperlinkedModelSerializer):def get_fields(self, *args, **kwargs):fields = super(PurchaseSerializer, self).get_fields(*args, **kwargs)fields['purchaser'].queryset = permitted_objects(self.context['view'].request.user, fields['purchaser'].queryset)return fieldsclass Meta:model = Purchase

permitted_objects is a function which takes a user and a query, and returns a filtered query which only contains objects that the user has permission to link to. This seems to work both for validation and for the browsable API dropdown fields.

https://en.xdnf.cn/q/26287.html

Related Q&A

How to clear GPU memory after PyTorch model training without restarting kernel

I am training PyTorch deep learning models on a Jupyter-Lab notebook, using CUDA on a Tesla K80 GPU to train. While doing training iterations, the 12 GB of GPU memory are used. I finish training by sav…

cryptography is required for sha256_password or caching_sha2_password

Good day. Hope your all are well. Can someone help me with fix this? Im new to the MySQL environment. Im trying to connect to MySQL Database remotely. I used the following python code and got this err…

Django: How to access original (unmodified) instance in post_save signal

I want to do a data denormalization for better performance, and put a sum of votes my blog post receives inside Post model:class Post(models.Model):""" Blog entry """autho…

timeit and its default_timer completely disagree

I benchmarked these two functions (they unzip pairs back into source lists, came from here): n = 10**7 a = list(range(n)) b = list(range(n)) pairs = list(zip(a, b))def f1(a, b, pairs):a[:], b[:] = zip(…

How to pickle and unpickle to portable string in Python 3

I need to pickle a Python3 object to a string which I want to unpickle from an environmental variable in a Travis CI build. The problem is that I cant seem to find a way to pickle to a portable string …

Using RabbitMQ is there a way to look at the queue contents without a dequeue operation?

As a way to learn RabbitMQ and python Im working on a project that allows me to distribute h264 encodes between a number of computers. The basics are done, I have a daemon that runs on Linux or Mac th…

Pip default behavior conflicts with virtualenv?

I was following this tutorial When I got to virtualenv flask command, I received this error message: Can not perform a --user install. User site-packages are not visible in this virtualenv.This makes s…

How to update user password in Django Rest Framework?

I want to ask that following code provides updating password but I want to update password after current password confirmation process. So what should I add for it? Thank you.class UserPasswordSeriali…

ImportError: No module named xlrd

I am currently using PyCharm with Python version 3.4.3 for this particular project.This PyCharm previously had Python2.7, and I upgraded to 3.4.3.I am trying to fetch data from an Excel file using Pand…

How do I automatically fix lint issues reported by pylint?

Just like we have "eslint --fix" to automatically fix lint problems in Javascript code, do we have something for pylint too for Python code?