How can I perform some logic prior to saving a record within my generic view? I believe the actual saving logic occurs within super().create()
.
The request within create()
looks like this
<QueryDict: {'csrfmiddlewaretoken': ['5WvMZnoBMCUjmlMBaacLnx6Pxt3jUDvHWHvo90ORumYrClkebcx7NJZpmWASRIyG'], 'user': ['1'], 'address': ['3E8ociqZa9mZUSwGdSmAEMAoAxBK3FNDcd']}>
view
class WalletListCreateAPIView(generics.ListCreateAPIView):
queryset = Wallet.objects.all()
serializer_class = WalletSerializer
def create(self, request, *args, **kwargs):
# Some logic here prior to saving
return super().create(request, *args, **kwargs)
For instance, I would like to create the value for balance
instead of relying on the value from the request
class Wallet(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
address = models.CharField(max_length=34)
balance = models.DecimalField(default=0, max_digits=16, decimal_places=8)
slug = models.SlugField(max_length=34, blank=True, null=True)
CodePudding user response:
This is the flow when you are saving your request data into model Also please check the syntax create -> perform_create -> serializer's create back to perform create then back to create
class WalletListCreateAPIView(generics.ListCreateAPIView):
queryset = Wallet.objects.all()
serializer_class = WalletSerializer
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
wallet = self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(
self.get_response_data(user),
status=status.HTTP_201_CREATED,
headers=headers,
)
def perform_create(self, serializer):
wallet = serializer.save(user=self.request.user) # if you want to change how you want to save from serializer to your model then you should override create method of serializer as I have shown below
wallet.balance = 30
wallet.save()
return wallet
# serializers.py
class WalletSerializer(serializers.ModelSerializer):
class Meta:
model = Wallet
fields = "__all__"
def create(self, validated_data):
# here in validated data you will receive your request data after validation If you want to discard any request value you can do here
balance = validated_data.pop("balance", None)
wallet = Wallet.objects.create(**validated_data)
return wallet
CodePudding user response:
You can override model save method
class Wallet(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
address = models.CharField(max_length=34)
balance = models.DecimalField(default=0, max_digits=16, decimal_places=8)
slug = models.SlugField(max_length=34, blank=True, null=True)
def save(self, *args, **kwargs):
if not self.pk:
#You can write own logic here
self.balance = 10
super(Wallet, self).save(*args, **kwargs)
CodePudding user response:
I understand your problem.
you want to override create method in generics.ListCreateAPIView.
so you have to define some method, here you want to create new record so you want to define post method and in post method you can override create method.
class WalletListCreateAPIView(generics.ListCreateAPIView):
queryset = Wallet.objects.all()
serializer_class = WalletSerializer
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
NOTE: - as per your Wallet model address field is not blank, so you should have pass address. then run it.