I am trying to post json file and save the models into database. AttributeName and AttributeValue is generated correctly but Attribute is saved without “nazev_atributu_id” and “hodnota_atributu_id”.
[
{
"AttributeName": {
"id": 2,
"nazev": "Barva"
}
},
{
"AttributeValue": {
"id": 2,
"hodnota": "modrá"
}
},
{
"Attribute": {
"id": 1,
"nazev_atributu_id": 2,
"hodnota_atributu_id": 2
}
}
]
models.py
from django.db import models
class AttributeValue(models.Model):
unique_id = models.AutoField(primary_key=True)
id = models.IntegerField(unique=True)
hodnota = models.CharField(max_length=255, null=True, blank=True)
def __str__(self):
return f"AttributeValue with id: {self.id}"
class AttributeName(models.Model):
unique_id = models.AutoField(primary_key=True)
id = models.IntegerField()
nazev = models.CharField(max_length=255, null=True, blank=True)
kod = models.CharField(max_length=255, null=True, blank=True)
zobrazit = models.BooleanField(default=False)
def __str__(self):
return f"AttributeName with id: {self.id}"
class Attribute(models.Model):
unique_id = models.AutoField(primary_key=True)
id = models.IntegerField(unique=True)
nazev_atributu_id = models.ManyToManyField(AttributeName, through='AttributeAttributeNameMapping')
hodnota_atributu_id = models.ManyToManyField(AttributeValue, through='AttributeAttributeValueMapping')
def __str__(self):
return f"Attribute with id: {self.id}"
class AttributeAttributeNameMapping(models.Model):
attribute = models.ForeignKey(Attribute, on_delete=models.CASCADE)
attribute_name = models.ForeignKey(AttributeName, on_delete=models.CASCADE)
class Meta:
unique_together = ('attribute', 'attribute_name')
class AttributeAttributeValueMapping(models.Model):
attribute = models.ForeignKey(Attribute, on_delete=models.CASCADE)
attribute_value = models.ForeignKey(AttributeValue, on_delete=models.CASCADE)
class Meta:
unique_together = ('attribute', 'attribute_value')
serializer
from rest_framework import serializers
from .models import *
class AttributeNameSerializer(serializers.ModelSerializer):
class Meta:
model = AttributeName
fields = '__all__'
class AttributeValueSerializer(serializers.ModelSerializer):
class Meta:
model = AttributeValue
fields = '__all__'
class AttributeSerializer(serializers.ModelSerializer):
nazev_atributu_id = serializers.SlugRelatedField(queryset=AttributeName.objects.all(),slug_field='id')
hodnota_atributu_id = serializers.SlugRelatedField(queryset=AttributeValue.objects.all(),slug_field='id')
class Meta:
model = Attribute
fields = ["unique_id", "id", "nazev_atributu_id", "hodnota_atributu_id"]
def create(self, validated_data):
# Extract many-to-many fields from the validated data
print("**************************")
print(validated_data)
print("**************************")
nazev_atributu_id = validated_data.pop('nazev_atributu_id')
hodnota_atributu_id = validated_data.pop('hodnota_atributu_id')
# Create the Attribute instance
attribute = Attribute.objects.create(**validated_data)
print("???????????????????")
print(nazev_atributu_id.__dict__)
print(hodnota_atributu_id.__dict__)
print("?????????????")
print(attribute, type(attribute))
print(attribute.__dict__)
print("------------------")
print(attribute.nazev_atributu_id)
print(attribute.hodnota_atributu_id)
print("------------------")
# Set many-to-many relationships
attribute.nazev_atributu_id.add(nazev_atributu_id)
attribute.hodnota_atributu_id.add(hodnota_atributu_id)
print("////////////////////")
print(attribute.__dict__)
print("////////////////////")
return attribute
But still cant find out why attribute is same before and after
attribute.nazev_atributu_id.add(nazev_atributu_id)
attribute.hodnota_atributu_id.add(hodnota_atributu_id)
This is print output after calling post request:
**************************
{'id': 1, 'nazev_atributu_id': <AttributeName: AttributeName with id: 2>, 'hodnota_atributu_id': <AttributeValue: AttributeValue with id: 2>}
**************************
???????????????????
{'_state': <django.db.models.base.ModelState object at 0x000001E7E56E99D0>, 'unique_id': 206, 'id': 2, 'nazev': 'Barva', 'kod': None, 'zobrazit': False}
{'_state': <django.db.models.base.ModelState object at 0x000001E7E56E9070>, 'unique_id': 214, 'id': 2, 'hodnota': 'modrá'}
?????????????
Attribute with id: 1 <class 'api.models.Attribute'>
{'_state': <django.db.models.base.ModelState object at 0x000001E7E56E9310>, 'unique_id': 78, 'id': 1}
------------------
api.AttributeName.None
api.AttributeValue.None
------------------
////////////////////
{'_state': <django.db.models.base.ModelState object at 0x000001E7E56E9310>, 'unique_id': 78, 'id': 1}
////////////////////
views
class LoadJson(viewsets.ModelViewSet):
def create(self, request):
post_successful = True
over_all_result_ok = []
over_all_result_nok = []
sorted_json = sort_json_data(request.data, get_model_ordering())
for item in sorted_json:
model_type = list(item.keys())[0]
model_values = list(item.values())[0]
result = serialize_model(model_type, model_values)
if result[0] is False:
post_successful = False
add_result_into_dict(over_all_result_nok, model_type, result)
else:
add_result_into_dict(over_all_result_ok, model_type, result)
if post_successful:
return Response({"status": over_all_result_ok}, status=status.HTTP_201_CREATED)
return Response({"status": over_all_result_nok}, status=status.HTTP_400_BAD_REQUEST)
def get_model_ordering():
# model_ordering = [
# 'AttributeName', 'AttributeValue', 'Attribute',
# 'Product', 'ProductAttributes', 'Image',
# 'ProductImage', 'Catalog'
# ]
model_ordering = [
'AttributeName', 'AttributeValue', 'Attribute',
]
return model_ordering
def sort_json_data(json_data, model_ordering):
sorted_list = []
for process in model_ordering:
for item in json_data:
if list(item.keys())[0] == process:
sorted_list.append(item)
return sorted_list
def add_result_into_dict(over_all_result, model_type, result):
over_all_result.append(
{
"model_type": model_type,
"result": result[0],
"message": result[1]
}
)
return over_all_result
def serialize_model(model_type, model_values):
serializer_class = SerializersLink().get_serializer_class(model_type)
if serializer_class:
serializer = serializer_class(data=model_values)
if serializer.is_valid():
serializer.save()
return True, f"Json data '{model_values}' for model '{model_type}' are correct according serializer"
else:
return False, f"Invalid json data '{model_values}' input in model type: '{model_type}'"
else:
return False, f"Not implemented model type: '{model_type}'"
class LoadJson(viewsets.ModelViewSet):
def create(self, request):
post_successful = True
over_all_result_ok = []
over_all_result_nok = []
sorted_json = sort_json_data(request.data, get_model_ordering())
for item in sorted_json:
model_type = list(item.keys())[0]
model_values = list(item.values())[0]
result = serialize_model(model_type, model_values)
if result[0] is False:
post_successful = False
add_result_into_dict(over_all_result_nok, model_type, result)
else:
add_result_into_dict(over_all_result_ok, model_type, result)
if post_successful:
return Response({"status": over_all_result_ok}, status=status.HTTP_201_CREATED)
return Response({"status": over_all_result_nok}, status=status.HTTP_400_BAD_REQUEST)
class SerializersLink:
def __init__(self):
# self._map_dict = {
# "AttributeName": AttributeNameSerializer,
# "AttributeValue": AttributeValueSerializer,
# "Attribute": AttributeSerializer,
# "Product": ProductSerializer,
# "ProductAttributes": ProductAttributesSerializer,
# "Image": ImageSerializer,
# "ProductImage": ProductImageSerializer,
# "Catalog": CatalogSerializer,
# }
self._map_dict = {
"AttributeName": AttributeNameSerializer,
"AttributeValue": AttributeValueSerializer,
"Attribute": AttributeSerializer,
}
def get_serializer_class(self, model_name):
if model_name in self._map_dict:
return self._map_dict[model_name]
return False