116👍
Off the top of my head, you can just override the perform_create()
method:
class PhotoListAPIView(generics.ListCreateAPIView):
...
def perform_create(self, serializer):
serializer.save(user=self.request.user)
Give that a shot and let me know if it works
75👍
You can use CurrentUserDefault
:
user = serializers.PrimaryKeyRelatedField(
read_only=True,
default=serializers.CurrentUserDefault()
)
- [Django]-React Error: Target Container is not a DOM Element
- [Django]-Django set field value after a form is initialized
- [Django]-Django model "doesn't declare an explicit app_label"
47👍
It depends on your use case. If you want it to be “write-only”, meaning DRF automatically populates the field on write and doesn’t return the User
on read, the most straight-forward implementation according to the docs would be with a HiddenField
:
class PhotoListAPIView(generics.ListCreateAPIView):
user = serializers.HiddenField(
default=serializers.CurrentUserDefault(),
)
If you want want it to be readable, you could use a PrimaryKeyRelatedField
while being careful that your serializer pre-populates the field on write – otherwise a user could set the user
field pointing to some other random User
.
class PhotoListAPIView(generics.ListCreateAPIView):
user = serializers.PrimaryKeyRelatedField(
# set it to read_only as we're handling the writing part ourselves
read_only=True,
)
def perform_create(self, serializer):
serializer.save(user=self.request.user)
Finally, note that if you’re using the more verbose APIView
instead of generics.ListCreateAPIView
, you have to overwrite create
instead of perform_create
like so:
class PhotoListAPIView(generics.ListCreateAPIView):
user = serializers.PrimaryKeyRelatedField(
read_only=True,
)
def create(self, validated_data):
# add the current User to the validated_data dict and call
# the super method which basically only creates a model
# instance with that data
validated_data['user'] = self.request.user
return super(PhotoListAPIView, self).create(validated_data)
- [Django]-How to Unit test with different settings in Django?
- [Django]-Import data from excel spreadsheet to django model
- [Django]-Django – how to create a file and save it to a model's FileField?
20👍
You can avoid passing the user
in your request and you won’t see it in the output but DRF will populate it automatically:
from rest_framework import serializers
class MyModelSerializer(serializers.ModelSerializer):
user = serializers.HiddenField(default=serializers.CurrentUserDefault())
class Meta:
model = models.MyModel
fields = (
'user',
'other',
'fields',
)
- [Django]-Django-reversion and related model
- [Django]-Override existing Django Template Tags
- [Django]-How to write setup.py to include a Git repository as a dependency
15👍
As of DRF version 3.8.0 (Pull Request discussion), you can override save()
in serializer.
from rest_framework import serializers
...
class PostSerializer(serializers.ModelSerializer):
user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())
class Meta:
model = Post
fields = ['id', 'user', 'photo']
def save(self, **kwargs):
"""Include default for read_only `user` field"""
kwargs["user"] = self.fields["user"].get_default()
return super().save(**kwargs)
- [Django]-Django composite unique on multiple model fields
- [Django]-Django Templating: how to access properties of the first item in a list
- [Django]-PyCharm: DJANGO_SETTINGS_MODULE is undefined
6👍
@DaveBensonPhillips’s answer might work in your particular case for some time, but it is not very generic since it breaks OOP inheritance chain.
ListCreateAPIView
inherits from CreateModelMixin
which saves the serializer already. You should always strive to get the full chain of overridden methods executed unless you have a very good reason not to. This way your code stays DRY and robust against changes:
class PhotoListAPIView(generics.ListCreateAPIView):
...
def perform_create(self, serializer):
serializer.validated_data['user'] = self.request.user
return super(PhotoListAPIView, self).perform_create(serializer)
- [Django]-How can I change the default Django date template format?
- [Django]-New url format in Django 1.9
- [Django]-Is there a list of Pytz Timezones?
4👍
You will have to override the default behavior of how generics.ListCreateAPIView
creates an object.
class PhotoListAPIView(generics.ListCreateAPIView):
queryset = Post.objects.filter(hidden=False)
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get_serializer_class(self):
if self.request.method == 'POST':
return CreatePostSerializer
else:
return ListPostSerializer
def create(self, request, *args, **kwargs):
# Copy parsed content from HTTP request
data = request.data.copy()
# Add id of currently logged user
data['user'] = request.user.id
# Default behavior but pass our modified data instead
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
The .get_serializer_class()
is not necessary as you can specify which fields are read-only from your serializer, but based on the projects I have worked on, I usually end up with ‘asymmetric’ serializers, i.e. different serializers depending on the intended operation.
- [Django]-How do I get the object if it exists, or None if it does not exist in Django?
- [Django]-Check permission inside a template in Django
- [Django]-What does error mean? : "Forbidden (Referer checking failed – no Referer.):"
1👍
Try this:
def post(self, request, format=None)
serializer = ProjectSerializer(data=request.data)
request.data['user'] = request.user.id
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST
- [Django]-Django vs. Model View Controller
- [Django]-Whats the difference between using {{STATIC_URL}} and {% static %}
- [Django]-Function decorators with parameters on a class based view in Django
1👍
This is what works for me in serializers.py, where I am also using nested data. I want to display created_by_username without having to lookup other users.
class ListSerializer(serializers.ModelSerializer):
"""
A list may be created with items
"""
items = ItemSerializer(many=True)
# automatically set created_by_id as the current user's id
created_by_id = serializers.PrimaryKeyRelatedField(
read_only=True,
)
created_by_username = serializers.PrimaryKeyRelatedField(
read_only=True
)
class Meta:
model = List
fields = ('id', 'name', 'description', 'is_public',
'slug', 'created_by_id', 'created_by_username', 'created_at',
'modified_by', 'modified_at', 'items')
def create(self, validated_data):
items_data = validated_data.pop('items', None)
validated_data['created_by_id'] = self.context['request'].user
validated_data['created_by_username'] = self.context['request'].user.username
newlist = List.objects.create(**validated_data)
for item_data in items_data:
Item.objects.create(list=newlist, **item_data)
return newlist
- [Django]-How do I perform HTML decoding/encoding using Python/Django?
- [Django]-Complete django DB reset
- [Django]-Rendering a template variable as HTML
0👍
I wrote an extension to DRF’s serializer below
from rest_framework import serializers
class AuditorBaseSerializer(serializers.Serializer):
created_by = serializers.StringRelatedField(default=serializers.CurrentUserDefault(), read_only=True)
updated_by = serializers.StringRelatedField(default=serializers.CurrentUserDefault(), read_only=True)
def save(self, **kwargs):
# if creating record.
if self.instance is None:
kwargs["created_by"] = self.fields["created_by"].get_default()
kwargs["updated_by"] = self.fields["updated_by"].get_default()
return super().save(**kwargs)
and it can be used as follows
class YourSerializer(serializers.ModelSerializer, AuditorBaseSerializer):
class Meta:
model = SelfEmployedBusiness
fields = (
'created_by',
'updated_by',
)
- [Django]-Getting Values of QuerySet in Django
- [Django]-How do I include related model fields using Django Rest Framework?
- [Django]-Profiling Django