Reputation: 2040
i have three models named Smoker,Switch,Survey i have smoker as foreign key in Switch model and switch as foreign key in Survey model
class Smoker(models.Model):
first_name = models.CharField(max_length=50, blank=True, null=True)
last_name = models.CharField(max_length=50, blank=True, null=True)
mobile = models.IntegerField(null=True, blank=True)
gender = models.BooleanField(blank=True, null=True)
age = models.ForeignKey(Age,models.DO_NOTHING,blank=True, null=True)
occupation = models.ForeignKey(Occupation, models.DO_NOTHING, blank=True, null=True)
class Switch(models.Model):
time = models.TimeField(blank=True, null=True)
count_outers = models.IntegerField(blank=True, null=True)
count_packs = models.IntegerField(blank=True, null=True)
smoker = models.ForeignKey(Smoker, models.DO_NOTHING, blank=True, null=True)
new_brand = models.ForeignKey(NewBrand, models.DO_NOTHING, blank=True, null=True)
new_sku = models.ForeignKey(NewSku, models.DO_NOTHING, blank=True, null=True)
# def __str__(self):
# return self.time.strftime("%H:%M")
class Survey(models.Model):
user = models.ForeignKey(User, models.DO_NOTHING, blank=True, null=True)
date = models.DateField(null=True, blank=True)
bool_switch = models.BooleanField(null=True, blank=True)
reason = models.ForeignKey(Reason, models.DO_NOTHING, null=True, blank=True)
shift = models.ForeignKey(ShiftingTime, models.DO_NOTHING, null=True, blank=True)
current_brand = models.ForeignKey(CurrentBrand, models.DO_NOTHING, null=True, blank=True)
current_sku = models.ForeignKey(CurrentSku, models.DO_NOTHING, null=True, blank=True)
pos = models.ForeignKey(Pos, models.DO_NOTHING, null=True, blank=True)
switch = models.ForeignKey(Switch, models.DO_NOTHING, null=True, blank=True)
and here i have my serializers:
class SmokerSerializer(serializers.ModelSerializer):
class Meta:
model = Smoker
fields = '__all__'
class SwitchSerializer(serializers.ModelSerializer):
smoker = SmokerSerializer()
class Meta:
model = Switch
fields = '__all__'
def create(self, validated_data):
smoker_data = validated_data.pop('smoker', None)
if smoker_data:
smoker = Smoker.objects.create(**smoker_data)
validated_data['smoker'] = smoker
return Switch.objects.create(**validated_data)
class SurveySerializer(serializers.ModelSerializer):
switch = SwitchSerializer()
class Meta:
model = Survey
fields = '__all__'
def create(self, validated_data):
switch_data = validated_data.pop('switch', None)
if switch_data:
switch = Switch.objects.create(**switch_data)
validated_data['switch'] = switch
return Survey.objects.create(**validated_data)
and i make a generic for for Creating and listing all the survey
class SurveyCreateAPIView(generics.ListCreateAPIView):
def get_queryset(self):
return Survey.objects.all()
serializer_class = SurveySerializer
for each displayed survey i have to display switch data related to it and inside the switch object i need to display the smoker object inside it so each survey object must look like this
{
"id": 11,
"switch": {
"id": 12,
"smoker": {
"firstname":"sami",
"lastname:"hamad",
"mobile":"7983832",
"gender":"0",
"age":"2",
"occupation":"2"
},
"time": null,
"count_outers": 5,
"count_packs": 7,
"new_brand": 2,
"new_sku": 2
},
"date": "2018-12-08",
"bool_switch": true,
"user": 7,
"reason": 3,
"shift": 2,
"current_brand": 6,
"current_sku": 4,
"pos": 2
},
but when i make a POST request it is giving me this error
ValueError at /api/v2/surveysync/ Cannot assign "OrderedDict([('first_name', 'aline'), ('last_name', 'youssef'), ('mobile', 7488483), ('gender', False), ('age', ), ('occupation', )])": "Switch.smoker" must be a "Smoker" instance.
so please help and thank you so much!
Upvotes: 0
Views: 141
Reputation: 6296
You're going along the right path but you're saving the switch objects manually instead of allowing the SwitchSerializer
do it for you. Same thing with create method in switch serializer. It should be this way:
class SmokerSerializer(serializers.ModelSerializer):
class Meta:
model = Smoker
fields = '__all__'
class SwitchSerializer(serializers.ModelSerializer):
smoker = SmokerSerializer()
class Meta:
model = Switch
fields = '__all__'
def create(self, validated_data):
smoker_data = validated_data.pop('smoker', None)
if smoker_data:
serializer = SmokerSerializer(data=smoker_data, context=self.context)
if serializer.is_valid():
validated_data['smoker'] = serializer.save()
return super().create(validated_data)
class SurveySerializer(serializers.ModelSerializer):
switch = SwitchSerializer()
class Meta:
model = Survey
fields = '__all__'
def create(self, validated_data):
switch_data = validated_data.pop('switch', None)
if switch_data:
serializer = SwitchSerializer(data=switch_data, context=self.context)
if serializer.is_valid():
validated_data['switch'] = serializer.save()
return super().create(validated_data)
Upvotes: 1
Reputation: 887
In SwitchSerializer
you defined the create
function as a method of the inner Meta
class and not as a member of SwitchSerializer
class. Try this
class SwitchSerializer(serializers.ModelSerializer):
smoker = SmokerSerializer()
class Meta:
model = Switch
fields = '__all__'
def create(self, validated_data):
smoker_data = validated_data.pop('smoker', None)
if smoker_data:
smoker = Smoker.objects.create(**smoker_data)
validated_data['smoker'] = smoker
return Switch.objects.create(**validated_data)
Upvotes: 0