Django Rest Framework getting Bad Request:400 error with serializer errors that I thought I took care of but I can't figure out where I went wrong? - serialization

I am trying to make a post request through insomnia to create a snake instance, but I am getting a Bad Request:400 error. I printed the serializer errors and got this:
{
'owner': [ErrorDetail(string='Incorrect type. Expected URL string, received ReturnDict.', code='incorrect_type')],
'birthday': [ErrorDetail(string='This field is required.', code='required')],
'date_aquired': [ErrorDetail(string='This field is required.', code='required')],
'species': [ErrorDetail(string='Incorrect type. Expected URL string, received ReturnDict.', code='incorrect_type')],
'breeder_id': [ErrorDetail(string='This field is required.', code='required')],
'mother': [ErrorDetail(string='This field is required.', code='required')],
'father': [ErrorDetail(string='This field is required.', code='required')]
}
Here is my serializer which I thought would take care of the null/blank fields:
class SnakeDetailSerializer(serializers.HyperlinkedModelSerializer):
href = serializers.HyperlinkedIdentityField(view_name="api_species_detail")
birthday = serializers.DateField(allow_null=True)
date_aquired = serializers.DateField(allow_null=True)
enclosure_id = serializers.CharField(allow_null=True, allow_blank=True)
breeder_id = serializers.CharField(allow_null=True, allow_blank=True)
father = serializers.CharField(allow_null=True, allow_blank=True)
mother = serializers.CharField(allow_null=True, allow_blank=True)
class Meta:
model = Snake
fields = [
'href',
'id',
'owner',
'name',
'age',
'birthday',
'date_aquired',
'gender',
'status',
'weight',
'enclosure_id',
'species',
'is_cbb',
'is_imported',
'breeder_id',
'mother',
'father'
]
Here is my model:
class Snake(models.Model):
# BASIC INFO
owner = models.ForeignKey(settings.AUTH_USER_MODEL,
related_name="collection",
on_delete=models.CASCADE
)
STATUS_CHOICES = (
('Active', 'Active'),
('Deceased', 'Deceased'),
('Quarantine', 'Quarantine'),
('For Sale', 'For Sale'),
('On Loan', 'On Loan'),
('Reserved', 'Reserved'),
('Sold', 'Sold')
)
GENDER_CHOICES = (
('M', 'Male'),
('F', 'Female'),
('NA', 'Unknown')
)
name = models.CharField(max_length=255)
age = models.SmallIntegerField()
birthday = models.DateField(null=True, blank=True)
date_aquired = models.DateField(null=True, blank=True)
status = models.CharField(max_length=10, choices=STATUS_CHOICES)
gender = models.CharField(max_length=2, choices=GENDER_CHOICES)
weight = models.DecimalField(max_digits=10, decimal_places=2)
enclosure_id = models.CharField(max_length=255, null=True, blank=True)
# SPECIES INFO
species = models.ForeignKey(SpeciesInfo, related_name="snakes", on_delete=models.PROTECT)
# LINEAGE INFO
is_cbb = models.BooleanField(default=False)
is_imported = models.BooleanField(default=False)
breeder_id = models.CharField(max_length=255, null=True, blank=True)
mother = models.CharField(max_length=255, null=True, blank=True)
father = models.CharField(max_length=255, null=True, blank=True)
here is my view:
#api_view(['GET', 'POST'])
def api_list_snakes(request):
if request.method == 'GET':
snakes = Snake.objects.all()
serializer = SnakeListSerializer(snakes, many=True)
return Response(
{'snakes': serializer.data}
)
else:
data = JSONParser().parse(request)
# print(data)
species = SpeciesInfo.objects.get(id=data["species"])
species_serialized = SpeciesInfoSerializer(species, context={'request':request})
owner = GetUserSerializer(request.user)
data['owner'] = owner.data
data["species"] = species_serialized.data
serializer = SnakeDetailSerializer(data=data, context={'request':request})
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=201)
print(serializer.errors)
return Response(serializer.data, status=400)
I have also added a photo of the insomnia request.insomnia_request
I thought adding the allow_null and allow_blank on the fields would correct the bad request error but it doesn't seem to have changed anything I am also getting errors for my foreign key fields and I am not sure why?
Help would be very much appreciated! Thanks!
I tried to add the fields that were allowed to be blank/null to the serializer here:
class SnakeDetailSerializer(serializers.HyperlinkedModelSerializer):
href = serializers.HyperlinkedIdentityField(view_name="api_species_detail")
birthday = serializers.DateField(allow_null=True)
date_aquired = serializers.DateField(allow_null=True)
enclosure_id = serializers.CharField(allow_null=True, allow_blank=True)
breeder_id = serializers.CharField(allow_null=True, allow_blank=True)
father = serializers.CharField(allow_null=True, allow_blank=True)
mother = serializers.CharField(allow_null=True, allow_blank=True)
and I expected that to correct the errors saying that they were required fields but they did not.
I also thought I had corrected the Foreign Key issues but it says they are expected a url string? I was using the id and it is getting the correct one so I'm not sure why it is mad about it

I figured out how to fix my required field error. I had to add required=True to the serializer fields but I still can't get the foreign keys to work

Related

Update records on one2many fields in wizard for odoo16

Geting Issue 'TypeError: unhashable type: 'dict' for insert values in one2many field from onchange method in odoo16
My code is below:
class EmployeeAddWizard(models.TransientModel):
_name = 'employee.add.wizard'
line_ids = fields.One2many('employee.goal.add.line', 'wizard_id', string="Lines")
#api.onchange('challenge_id', 'employee_id')
def _onchange_action_goal_add(self):
r = []
value = {}
self.line_ids = {}
if self.challenge_id and self.employee_id:
goal_records = self.env['gamification.challenge.line'].search([('challenge_id', '=', self.challenge_id.id)])
for emp in self.employee_id:
for line in goal_records:
data = {'wizard_id': self.id, # Other table m2o
'goal_definition_id': line.definition_id.id,
'goal_rating': 0.0,
'goal_target': line.target_goal,
'employee_id': emp.id,
}
r.append(data)
value.update(records=r)
self.line_ids = value['records']
class GoalLine(models.Model):
_name = 'employee.goal.add.line'
wizard_id = fields.Integer()
goal_definition_id = fields.Many2one('gamification.goal.definition', string='Goal Definition', required=True, ondelete="cascade")
goal_rating = fields.Float('Rating', required=True)
goal_target = fields.Float('Target Value ', required=True)
employee_id = fields.Many2one('res.users', string="Employee", required=True, ondelete="cascade")
Thanks in advance
You passed a list of dicts which is not valid, you need to use special commands
Example:
r.append(Command.create(data))
or:
r.append((0, 0, data))
You can use Command.clear(), to remove previous lines if needed ( self.line_ids = {} should raise an error: ValueError: Wrong value).
Check this answer

Odoo - Filter Many2one not by _rec_name

I would like to filter m2o field, but not by default name (_rec_name).
class LecturerWorkday(models.Model):
_name = 'lecturer.workday'
_rec_name = 'lecturer_id'
name = fields.Selection([('sunday','Sunday'),('monday','Monday'),('tuesday','Tuesday'),
('wednesday','Wednesday'),('thursday','Thursday'),('friday','Friday'),('saturday','Saturday'),
], default='sunday',string="Workday", required=True)
lecturer_id = fields.Many2one('school.lecturer', string="Lecturer Name", invisible=True)
class SchoolLecturer(models.Model):
_name = 'school.lecturer'
name = fields.Char(string="Lecturer Name", required=True)
workday_id = fields.Many2one("lecturer.workday", string="Workday ID")
class LecturerTimeoff(models.Model):
_name = "lecturer.timeoff"
lecturer = fields.Many2one('school.lecturer', string="Lecturer Name")
day_m2o = fields.Many2one('lecturer.workday', string="Lecturer Workdays")
reason = fields.Char("Time off Reason")
#api.onchange('lecturer')
def get_lecturer_workday(self):
day_obj = self.env['lecturer.workday'].search([('lecturer_id', '=', self.lecturer.id)]).mapped('name')
day_list = []
for rec in day_obj:
day_list.append(rec)
res = {}
res['domain'] = {'day_m2o': [('name', '=', day_list)]}
return res
print (res)
My question are:
When I choose lecturer name, day_m2o should display the workday of selected lecturer name. I have been trying to compute it as above, but the result is still display lecturer name, instead of workday.
It seems that #api.onchange didn't update the result instantly whenever i clicked the new lecturer name who didn't have workday yet. How to fix this?
Thanks for your help

How to check if a record already exists or not in database in DRF?

I am working on DRF. I am creating an API of POST request that overriding its features. I want to add one functionality if a particular field value already exists in DB then, user cannot create post request and instead of it getting a message that he couldn't do it.
views.py
class PizzaOrderViewSet(viewsets.ModelViewSet):
http_method_names = ['get', 'put', 'patch', 'post']
def create(self, request, *args, **kwargs):
data = request.data
order = PizzaOrder.objects.create(
name=data['name'], flavours=data['flavours'],
number=data['number'], size=data['size'],
customer_name=data['customer_name'],
customer_address=data['customer_address']
)
order.save()
serializer = PizzaOrderSerializer(order)
return Response(serializer.data)
serializers.py
class PizzaOrderSerializer(serializers.ModelSerializer):
class Meta:
model = PizzaOrder
validators = [
UniqueTogetherValidator(
queryset=PizzaOrder.objects.all(),
fields=['name', 'flavours', 'size', 'customer_name', 'customer_address'],
message='This field should be unique'
)
]
models.py
from django.db import models
from datetime import datetime
FLAVOURS_CHOICE = (
('Margarita', 'Margarita'),
('Marinara', 'Marinara'),
('Salami', 'Salami'),
)
SIZE_CHOICE = (
('Small', 'Small'),
('Medium', 'Medium'),
('Large', 'Large'),
)
STATUS_CHOICE = (
('Open', 'Open'),
('Accepted', 'Accepted'),
('Preparing', 'Preparing'),
('OnWay', 'OnWay'),
('Delivered', 'Delivered'),
)
class PizzaOrder(models.Model):
name = models.CharField(max_length=50, blank=False)
flavours = models.CharField(max_length=20, choices=FLAVOURS_CHOICE)
quantity = models.IntegerField()
size = models.CharField(max_length=10, choices=SIZE_CHOICE)
customer_name = models.CharField(max_length=30, blank=False)
customer_address = models.TextField(blank=False)
ordered_time = models.DateTimeField(default=datetime.now, editable=False)
status = models.CharField(max_length=20, choices=STATUS_CHOICE, default='Open')
def __str__(self):
return self.name
class Meta:
ordering = ['-ordered_time']
unique_together = ('name', 'flavours', 'quantity', 'size')
How could I achieve this?

About the onchange method returning domain or warning in odoo8

I tried following the odoo8 official example,but not works for me:
class TestMove(models.Model):
_name = 'test.move'
_description = 'Stock Requisition Return'
num1 = fields.Float(string='num1')
num_float = fields.Float(string='num_float', compute="_compute_num_float", store=True)
num2 = fields.Integer(string='num2')
age = fields.Integer(compute='_compute_age')
age2 =fields.Integer(compute='_compute_age2', store=True)
now_list_price = fields.Float(
string='Now List Price', help='Now List Price', digits=(10, 10))
product_id = fields.Many2one(comodel_name='product.product')
......
#api.one
#api.onchange('num1')
def _onchange_num2(self):
now_ = self.num1 + 1
_logger.info('num2 is:%s', now_)
self.update({'num2': now_})
return {
'domain': {'product_id': [('id', 'in', [now_])]},
'warning': {'title': "Warning", 'message': "What is this?"}
}
class ProductProduct(models.Model):
_name = 'product.product'
_description = 'Product'
_rec_name = 'name'
name = fields.Char()
price_unit = fields.Float(default=Decimal('13.14'))
num2 has changed, but domain and warning are not returned;
Any suggestion please. Thanks in advance.
The issue is caused by #api.one decorator, just remove it and the onchange method should work correctly.

Django Rest Framework - Could not resolve URL for hyperlinked relationship using view name "field-detail"

I know that this inconvenient is very presented, may be that I need learn more about of serializer relationships
I have the following model:
class Field(models.Model):
FIELD_TYPE_NATURE = 'Grama natural'
FIELD_TYPE_ARTIFICIAL = 'Grama sintetica'
FIELD_TYPE_CHOICES = (
(FIELD_TYPE_NATURE, u'Grama natural'),
(FIELD_TYPE_ARTIFICIAL, u'Grama sintetica'),
)
MODALITY_11 = 'Fútbol 11'
MODALITY_8 = 'Fútbol 8'
MODALITY_CHOICES = (
(MODALITY_11, u'Fútbol 11'),
(MODALITY_8, u'Fútbol 8'),
)
name = models.CharField(
max_length=150,
unique=True,
db_index=True,
primary_key=True,
)
field_type = models.CharField(
choices=FIELD_TYPE_CHOICES,
default=False,
blank=False,
max_length=20,
verbose_name=('Tipo de material/grama de la cancha')
)
modality = models.CharField(
max_length=40,
blank=False,
verbose_name='Modalidad'
)
photo = models.ImageField(upload_to='fields', blank=True, null=True)
location = models.CharField(max_length=150, blank=False)
def __str__(self):
return '%s %s %s' % (self.name, self.field_type, self.location)
My serializer is the following:
class FieldSerializer(serializers.HyperlinkedModelSerializer):
#url = serializers.HyperlinkedIdentityField(view_name='field-detail',)
class Meta:
model = Field
fields = ('url', 'name','field_type','modality','photo','location')
My viewset is:
class FieldViewSet(viewsets.ModelViewSet):
queryset = Field.objects.all()
serializer_class = FieldSerializer
This is my router:
router = routers.DefaultRouter()
router.register(r'fields', FieldViewSet)
And my url:
...
url(r'^api/', include(router.urls)),
...
When I go to the http://localhost:8000/api/fields/ url I get the following message:
File "/home/bgarcial/.virtualenvs/fuupbol2/lib/python3.5/site-packages/rest_framework/relations.py", line 386, in to_representation
raise ImproperlyConfigured(msg % self.view_name)
django.core.exceptions.ImproperlyConfigured: Could not resolve URL for **hyperlinked relationship using view name "field-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.**
[11/Nov/2016 16:39:53] "GET /api/fields/ HTTP/1.1" 500 187477
When I use HyperlinkedIdentityField in my FieldSerializer class:
class FieldSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='field-detail',)
class Meta:
model = Field
fields = ('url', 'name','field_type','modality','photo','location')
I follow getting the same error.
Althought when I go to the url http://localhost:8000/api/fields/ I want get is a list of my objects, then is possible that I should put:
url = serializers.HyperlinkedIdentityField(view_name='field-list',)
?
I use HyperlinkedIdentityField according to:
This field can be applied as an identity relationship, such as the
'url' field on a HyperlinkedModelSerializer. It can also be used for
an attribute on the object.
I put the field-list in my view_name attribute and I get the error related
Could not resolve URL for hyperlinked relationship using view name "field-list". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.
I don't understand the situations when I should use view_name attribute in relation to if I wnt get a list objects, a object detail and so ... although here explain something about it.
When I should use HyperlinkedModelSerializer and ModelSerializer