Skip to content

fixing unique together validator for fields with source #7005

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

Closed
7 changes: 6 additions & 1 deletion rest_framework/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ def set_context(self, serializer):
"""
# Determine the existing instance, if this is an update operation.
self.instance = getattr(serializer, 'instance', None)
self.serializer = serializer

def enforce_required_fields(self, attrs):
"""
Expand Down Expand Up @@ -137,7 +138,11 @@ def filter_queryset(self, attrs, queryset):

# Determine the filter keyword arguments and filter the queryset.
filter_kwargs = {
field_name: attrs[field_name]
(
field_name
if field_name == self.serializer.fields[field_name].source
else self.serializer.fields[field_name].source
): attrs[field_name]
for field_name in self.fields
}
return qs_filter(queryset, **filter_kwargs)
Expand Down
60 changes: 60 additions & 0 deletions test_read_only_default/test_read_only_default.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from django.db import models
from rest_framework import serializers
from rest_framework.validators import (
UniqueTogetherValidator,
)

from rest_framework import viewsets
import json
from rest_framework import mixins
from rest_framework import generics
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.test import TestCase
from rest_framework import status


class ModelTwo(models.Model):
testfieldtwo = models.CharField(max_length=60, primary_key=True)

class ModelOne(models.Model):
testfield = models.ForeignKey(ModelTwo, on_delete=models.CASCADE)
alias = models.CharField(max_length=60)
name = models.CharField(max_length=60)

class Meta:
unique_together = ('testfield', 'name',)


class ExampleSerializer(serializers.ModelSerializer):
altername = serializers.CharField(source="testfield", default=ModelTwo(testfieldtwo="model 2 default"), read_only=True)

class Meta:
model = ModelOne
fields = ('altername' ,'alias', 'name')
validators = [
UniqueTogetherValidator(
queryset=ModelOne.objects.all(),
fields=('testfield', 'name')
)
]

class ExampleViewSet(mixins.CreateModelMixin,
mixins.UpdateModelMixin,
viewsets.ReadOnlyModelViewSet):

queryset = ModelOne.objects.all()
serializer_class = ExampleSerializer


class ExampleTests(TestCase):

def url(self):
return '/example/'

def test_created_successfully(self):
name = 'blab blah'
alias = 'ab ab'
response = self.client.post(self.url, {'name': name, 'alias': alias})
self.assertEqual(response.status_code, status.HTTP_201_CREATED, response.data)
11 changes: 11 additions & 0 deletions test_read_only_default/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from django.conf.urls import include, url
from rest_framework import routers
from test_read_only_default import ExampleViewSet

router = routers.DefaultRouter()
router.register(r'example', ExampleViewSet)

urlpatterns = [
url('', include(router.urls)),
url('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]