Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In browsable API unselecting the checkbox for a boolean field doesn't update the field, but using raw data does update the field #8762

Open
piotrsynowiec opened this issue Nov 16, 2022 · 9 comments

Comments

@piotrsynowiec
Copy link

I noticed that when I unselect the boolean field that was already True to set it to False via browsable API – the field doesn't update.

Here's an example:
https://capture.dropbox.com/k3xcrwjBS9aK4fVT

After unselecting "invoiced" and clicking PUT, the data stays the same (I edited the price value too):
https://capture.dropbox.com/bT46reH9ushS8nge

But when I edit the RAW data text field:
https://capture.dropbox.com/pDYjaAHHsvNqE79K

The value gets updated:
https://capture.dropbox.com/mC9UwhQBLrt1yEOE

It works on all of my endpoints the same way. I wonder if this is a bug or if I am doing something wrong.

@reddytocode
Copy link

Just FYI, GitHub allows you to upload images 😅
It would be helpful if you share also some code to see what may be happening here.

@piotrsynowiec
Copy link
Author

piotrsynowiec commented Nov 28, 2022

Here is the model:

`
class Currency(TimeStampedModel):
company = models.ForeignKey(Company,
on_delete=models.CASCADE,
related_name="companies")
name = models.CharField(choices=settings.CURRENCY_CHOICES,
default='USD',
max_length=3)
owner = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)

class Meta:
    verbose_name_plural = "Currencies"

def __str__(self):
    return self.name

``

here's the serializer:

`class CurrencySerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
company = serializers.PrimaryKeyRelatedField(read_only=True)
name = serializers.ChoiceField(choices=settings.CURRENCY_CHOICES)
owner = serializers.StringRelatedField()

class Meta:
    model = Currency
    fields = '__all__'

def create(self, validated_data):
    return Currency.objects.create(**validated_data)

def update(self, instance, validated_data):
    instance.name = validated_data.get('name', instance.name)
    instance.company = validated_data.get('company', instance.company)
    instance.owner = validated_data.get('owner', instance.owner)
    instance.save()
    return instance`

here're the views:

`class CurrencyListCreateAPIView(generics.ListCreateAPIView):
serializer_class = CurrencySerializer
permission_classes = [
IsAuthenticated,
IsOwner,
]

def perform_create(self, serializer):
    user = self.request.user
    kwarg_company = self.kwargs.get("company")
    company = get_object_or_404(Company, pk=kwarg_company, owner=user)

    if serializer.is_valid():
        currency_name = serializer.validated_data['name']
        if company:
            if Currency.objects.select_related('owner', 'company').filter(company_id=kwarg_company).filter(
                    name=currency_name).exists():
                raise ValidationError(
                    "You have already added this currency!")
            else:
                return serializer.save(owner=user, company=company)
        else:
            raise ValidationError("You don't own that Company")

def get_queryset(self):
    user = self.request.user
    kwarg_company = self.kwargs.get("company")

    return Currency.objects.select_related('company', 'owner').filter(
        owner=user).filter(
            company_id=kwarg_company).order_by("-created_at")`

@piotrsynowiec
Copy link
Author

Sorry, I don't know how to post the code so it is correctly shown.

@Peim8
Copy link

Peim8 commented Dec 15, 2022

Hi, is that issue already solved? If not - can I work on it?

@piotrsynowiec
Copy link
Author

It is not solved for me 🙂

@auvipy
Copy link
Member

auvipy commented Dec 15, 2022

Hi, is that issue already solved? If not - can I work on it?

you can work on it.

@fatelei
Copy link

fatelei commented Jan 17, 2023

ListCreateAPIView

this code is not right, ListCreateAPIView only support get and post, not support put

@FraCata00
Copy link

Please, use the ModelViewSet and ModelSerializers
https://www.django-rest-framework.org/api-guide/serializers/#modelserializer
https://www.django-rest-framework.org/api-guide/viewsets/#modelviewset

class CurrencySerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(read_only=True)
    company = serializers.PrimaryKeyRelatedField(read_only=True)
    name = serializers.ChoiceField(choices=settings.CURRENCY_CHOICES)
    owner = serializers.StringRelatedField()
    
    class Meta:
        model = Currency
        fields = ["id", "company", "name", "owner"]

image

You can spli the serializer and use different serializer in ModelViewSet with def_get_serializer_class base on self.action

Like:

# views.py
from rest_framework import viewsets

class MyModelViewSet(viewsets.ModelViewSet):
      # other 
      def get_serializer_class(self):
           if self.action == "create":
              # return create serializer class
           elif self.action in ["update", "partial_update"]:
             # return the serualizer class made for the PATCH/PUT
           # made last one for the list/retieve action

#serializers.py
class CurrencyUpdateSerializer(serializers.ModelSerializer):
    name = serializers.ChoiceField(choices=settings.CURRENCY_CHOICES)
    owner = serializers.StringRelatedField()
    
    class Meta:
        model = Currency
        fields = ["name", "owner"]

class CurrencyRetrieveListSerializer(serializers.ModelSerializer):
     class Meta:
        fields = "__all__"

You have more control for action of drf and the HTTP method
https://www.django-rest-framework.org/api-guide/viewsets/#viewset-actions

@Dostonbek1
Copy link

Hi, is that issue already solved? If not - can I work on it?

you can work on it.

I'm facing this same issue as well. Do you guys know when it could be fixed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants