Dont get field in result create method django rest framework - python

I have a method of creating clien. one of the body fields of my method is client_users which is not in my client model. He has a foreign key for clients. I overwrite the create method and it is ok. But when I return the method I have this error:
AttributeError: Got AttributeError when attempting to get a value for field `clientes_usuarios` on serializer `ClienteCreateSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Cliente` instance.
Original exception text was: 'Cliente' object has no attribute 'clientes_usuarios'.
My field in my serializer:
class ClienteCreateSerializer(serializers.ModelSerializer):
endereco_residencial = EnderecoSerializer(read_only=False)
endereco_cobranca = EnderecoSerializer(read_only=False,required=False)
contatos = ContatoClienteSerializer(many=True, read_only=False, required=False)
certificados = CertificadoSerializer(many=True, read_only=False, required=False)
email = serializers.EmailField(source='usuario.email')
cnpj = serializers.CharField(max_length=14, min_length=14, source='usuario.cpf_cnpj')
foto = serializers.CharField(required=False)
data_abertura = serializers.DateField(input_formats=settings.DATE_INPUT_FORMATS, required=False, allow_null=True)
clientes_usuarios = UsuarioClienteCreateSerializer(many=True,read_only=False)
I have outher methods like this and they works fine

Related

How to create 2 objects from separate models with a single serializer and also retrieve them from the database with a single serializer in Django RF?

I have 3 models: Maker, Item and MakerItem that creates the relation between the items and their makers:
class Maker(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
name = models.CharField(max_length=100)
class Item(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
name = models.CharField(max_length=100)
class MakerItem(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
item_id = models.ForeignKey(Item, on_delete=models.CASCADE)
maker_id = models.ForeignKey(Maker, on_delete=models.CASCADE)
the items can have a random amount of makers.
I want to create both the Item and the MakerItem objects at the same time with a single set of data,
for example if a Maker with id = "abcd" already exists, and I go to /item and send a POST request with the following data:
{
"name": "item1",
"makers": [
{
"maker_id": "abcd"
}
]
}
I want the serializer to create the Item object and the MakerItem object.
I have achieved this, with the following setup:
views.py
class ItemListCreate(ListCreateAPIView):
queryset = Item.objects.all()
serializer_class = ItemSerializer
serializers.py
class ItemSerializer(serializers.ModelSerializer):
class MakerItemSerializer(serializers.ModelSerializer):
class Meta:
model = MakerItem
exclude = ['id', 'item_id']
makers = MakerItemSerializer(many=True)
class Meta:
model = Item
fields = ['id', 'name', 'makers']
def create(self, validated_data):
maker_item_data = validated_data.pop('makers')
item_instance = Item.objects.create(**validated_data)
for each in maker_item_data:
MakerItem.objects.create(
item_id=check_instance,
maker_id=each['maker_id']
)
return item_instance
but when Django tries to return the created object, it always gives me the error:
AttributeError at /item/
Got AttributeError when attempting to get a value for field `makers` on serializer `ItemSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Item` instance.
Original exception text was: 'Item' object has no attribute 'makers'.
What am I doing wrong?
Thanks
EDIT: To clarify, the objects get created and populate the database correctly, but when the browsable API that DRF provides tries to display the created object, it gives me the error above.
Change:
class ItemSerializer(serializers.ModelSerializer):
class MakerItemSerializer(serializers.ModelSerializer):
class Meta:
model = MakerItem
exclude = ['id', 'item_id']
makers = MakerItemSerializer(many=True)
To:
class ItemSerializer(serializers.ModelSerializer):
class MakerItemSerializer(serializers.ModelSerializer):
class Meta:
model = MakerItem
exclude = ['id', 'item_id']
makers = MakerItemSerializer(many=True, source="makeritem_set")
Hope this works!
For clarity, you're attempting to serialise the reverse relationship between MakerItem and Item for this serialiser.
This means that the attribute on your object is automatically set by Django as fieldname_set but you can override this behaviour by setting the related_name kwarg on the field and then makemigrations and migrate it.
In your case you would need to do:
maker_id = models.ForeignKey(Maker, on_delete=models.CASCADE, related_name="maker_items")
And then update the field in the Meta to match the new field name, this way you don't have to manually specify source. Because actually the attribute "makers" is misleading, due to the fact its actually the MakerItem, not the Maker itself.
See https://docs.djangoproject.com/en/3.2/ref/models/relations/ for further details about this behaviour.

Object of type leave is not JSON serializable

{i am unable to get how to resolve this problem.i am trying to save a dict buy creating a model instance but i am getting error due to the foreign key in my leave model which is connected to hostel manager through one to many relation }
i have resolved this error but got new error Object of type leave is not JSON serializable i do not how to resolve this
and in my database the data i obtain through request is getting saved but the data which i got from other table by using jwt token is not getting saved
final_data= leave(**serializer)
views.py
class leaveview(APIView):
def post(self,request):
token = request.data['jwt']
if not token:
raise AuthenticationFailed('Unauthenticated')
try:
payload = jwt.decode(token,'secret',algorithms=['HS256'])
except jwt.ExpiredSignatureError:
raise AuthenticationFailed('Unauthenticated')
user=User.objects.filter(id=payload['id']).first()
serializer1=UserSerializers(user).data
serializer2 = leaveSerializers(data=request.data)
serializer2.is_valid(raise_exception=True)
serializer={**serializer1,**request.data}
del serializer["jwt"]
loc = hostel_manager.objects.get(hostel = serializer['hostel_name'])
del serializer['hostel_name']
del serializer['password']
a=leave.objects.create(**serializer,**{'hostel_name' : loc} )
a=leaveSerializers(a)
return Response(a.data)
models.py
class hostel_manager(models.Model):
hostel = models.CharField(max_length=100,primary_key=True)
class leave(models.Model):
name=models.CharField(max_length=100,null = True)
father_name=models.CharField(max_length=100,null=True)
branch=models.CharField(max_length=40,null=True)
coer_id=models.CharField(max_length=12,unique=True,null=True)
hostel_name = models.ForeignKey(hostel_manager,on_delete=models.CASCADE)
room_no = models.CharField(max_length=10)
where_to = models.CharField(max_length=100)
reason = models.CharField(max_length=300)
start_date = models.CharField(max_length = 100,null=True)
end_date = models.CharField(max_length=100,null=True)
phone_regex=RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+9999999999'. Up to 12 digits allowed.")
phone_number = models.CharField(validators=[phone_regex], max_length=17)
this is the error i got
File "d:\python\lib\json\encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type leave is not JSON serializable
serializer.py
class leaveSerializers(serializers.ModelSerializer):
class Meta:
model = leave
fields = ['id','hostel_name','room_no','where_to','reason','phone_number','start_date','end_date','name','father_name','branch','coer_id']
class hostelmanagerSerializers(serializers.ModelSerializer):
class Meta:
model = hostel_manager
fields = ['hostel']
Error message suggests that you are trying to assign hostel_name as a string/CharField. As per your model, it needs to be a hostel_manager object.
Not sure what your POST serializer or payload looks like but you'd probably want to set the hostel_manager_pk field to the kund kund bhawan's object's PK.

Django Rest Framework serializing queryset fetchedn with value_list

I'm trying to query a specific column from my table. I've tried doing it with this
team_lenDeserialized = RolesInTeam.objects.values_list('user_id', flat=True).filter(academic_year_id=9).filter(deleted=0)
team_lenDict = RolesInTeamSerializer(team_lenDeserialized, many=True)
team_len = orderedDictToJSON(team_lenDict.data)
After that I run it through a function that converts it to JSON
def orderedDictToJSON(orderedDict):
return json.loads(json.dumps(orderedDict))
then I go and manipulate it further. However if I try to serialize and convert the team_lenDeserialized I get an error that states
AttributeError: Got AttributeError when attempting to get a value for field `user_id` on
serializer RolesInTeamSerializer`.
The serializer field might be named incorrectly and not match any
attribute or key on the `int` instance.
Original exception text was: 'int' object has no attribute 'user_id'.
This is my model for that table
class RolesInTeam(models.Model):
user_id = models.IntegerField()
team_id = models.IntegerField()
role_id = models.IntegerField()
deleted = models.IntegerField()
academic_year_id = models.IntegerField()
class Meta:
managed = False
db_table = 'roles_in_team'
and my serializer
class RolesInTeamSerializer(serializers.ModelSerializer):
class Meta:
model = RolesInTeam
fields = ['id', 'user_id', 'team_id', 'role_id', 'deleted', 'academic_year_id']
I have no clue what's happening or why it's not working.
You can only serialize models instances with a ModelSerializer, and values_list() returns a queryset of tuples, so when you try to use the serializer over the queryset, you get the error.
If you make a regular query (team_lenDeserialized = RolesInTeam.objects.filter(academic_year_id=9).filter(deleted=0)), you would be able to serialize team_lenDeserialized.

DRF one to many serialization -- AttributeError from missing field

Error:
AttributeError at /stats/matches
Got AttributeError when attempting to get a value for field players on serializer MatchSerializer.
The serializer field might be named incorrectly and not match any attribute or key on the Match instance.
Original exception text was: 'Match' object has no attribute 'players'.
Models:
Every Match has 10 players.
class Match(models.Model):
tournament = models.ForeignKey(Tournament, blank=True)
mid = models.CharField(primary_key=True, max_length=255)
mlength = models.CharField(max_length=255)
win_rad = models.BooleanField(default=True)
class Player(models.Model):
match = models.ForeignKey(Match, on_delete=models.CASCADE)
playerid = models.CharField(max_length=255, default='novalue')
# There is also a Meta class that defines unique_together but its omitted for clarity.
Serializers:
class PlayerSerializer(serializers.ModelSerializer):
class Meta:
model = Player
fields = "__all__"
class MatchSerializer(serializers.ModelSerializer):
players = PlayerSerializer(many=True)
class Meta:
model = Match
fields = ("mid","players")
The MatchSerializer search for a players attribute in Match's instance, but it couldn't find and you get the following error:
AttributeError at /stats/matches
Got AttributeError when attempting to get a value for field players on
serializer MatchSerializer. The serializer field might be named
incorrectly and not match any attribute or key on the Match instance.
Original exception text was: 'Match' object has no attribute 'players'.
In DRF serializer, a parameter called source will tell explicitly where to look for the data. So, change your MatchSerializer as follow:
class MatchSerializer(serializers.ModelSerializer):
players = PlayerSerializer(many=True, source='player_set')
class Meta:
model = Match
fields = ("mid", "players")
Hope it helps.
The problem here is that Match model has not an attribute called players, remember that you are trying to get backwards relationship objects, so you need to use players_set as field as django docs says.
You could solve this in Two Ways
1. Adding a source parameter to the PlayerSerializer
class MatchSerializer(serializers.ModelSerializer):
players = PlayerSerializer(many=True, source='player_set')
class Meta:
model = Match
fields = ("mid", "players")
2. Change the lookup-field
class MatchSerializer(serializers.ModelSerializer):
player_set = PlayerSerializer(many=True)
class Meta:
model = Match
fields = ("mid","player_set")

How to use custom variables in serializers?

I want to create a serializer that uses the variables from my model and also counts how many data of the same id is found in the table.
I have created this, but it doesn't work:
class WebsiteSerializer(serializers.Serializer):
item_nr = serializers.IntegerField()
class Meta:
model = URL
fields = (
"id",
"item",
"status",
"item_nr "
)
def get_item_nr (self, obj):
obj.item_nr = Items.objects.filter(item_id=self.context.get(id)).count()
return obj.item_nr
This is the error that I get:
Got AttributeError when attempting to get a value for field item_nr
on serializer WebsiteSerializer. The serializer field might be named
incorrectly and not match any attribute or key on the URL instance.
Original exception text was: 'URL' object has no attribute 'item_nr '.
items_nr will be a SerializerMethodField not IntegerField
The field will be automatically assigned data type based on what you return in get_item_nr.
class WebsiteSerializer(serializers.Serializer):
item_nr = serializers.SerializerMethodField()
class Meta:
model = URL
fields = (
"id",
"item",
"status",
"item_nr "
)
def get_item_nr (self, obj):
obj.item_nr = Items.objects.filter(item_id=self.context.get(id)).count()
return obj.item_nr

Categories