Confused about editing many to many field with Editor
Confused about editing many to many field with Editor
Hi, I'm pretty confused about my many-to-many field editing. I've tried about 10 different approaches with different errors every time.
Currently I'm getting: {"type":["This field is required."],"companyname":["This field is required."]}
I have two simple Models:
class Companiestypechoice(models.Model):
business_type = models.CharField(max_length=50)
class Companies(models.Model):
companyname = models.CharField(max_length=100)
type = models.ManyToManyField(Companiestypechoice)
Two serializers:
class TypeSerializer(serializers.ModelSerializer):
class Meta:
model = Companiestypechoice
fields = ('__all__')
class CompanySerializer(serializers.ModelSerializer):
type = TypeSerializer(many=True)
class Meta:
model = Companies
fields = ('__all__')
A viewset:
class CompanyViewSet(viewsets.ModelViewSet):
queryset = Companies.objects.all().order_by('companyname')
serializer_class = CompanySerializer
My JSON looks like this:
[
{ "id": 1, "type": [
{ "id": 1,"business_type": "Customer" } ],
"companyname" : "AB flight" },
{ "id": 2, "type": [
{ "id": 1,"business_type": "Customer" },
{ "id": 2,"business_type": "Supplier" } ],
"companyname": "Alitalia" },
{ "id": 3, "type": [
{ "id": 1,"business_type": "Customer" }
] etc...
As per the manual I'm using column.data option to display business type/s in cells.
columns: [ { data: "type.[, ].business_type" ... } ]
Which works great.
When but when I try to edit or create the fields it gives me
BAD REQUEST 400: "type":["This field is required."],"companyname":["This field is required."]
My HTML:
$(document).ready(function() {
editor = new $.fn.dataTable.Editor( {
ajax: {
url: "api/companies.json",
headers: {'X-CSRFToken': '{{ csrf_token }}'}
},
table: "#table_id",
idSrc: 'id',
fields: [
{
label: "Company name:",
name: "companyname"
},
{
label: "Type:",
name: "type.[, ].business_type",
},
]
} );
oTable = $('#table_id').DataTable( {
dom: "Blrtip",
ajax: {
url: "api/companies.json",
dataSrc: ''
},
columns: [
{ data: "id",
visible: false,
searchable: false
},
{ data: "companyname",
title: "Comany Name"
},
{ data: "type.[, ].business_type",
title: "Business type"
}
],
select: true,
buttons: [
{ extend: "create", editor: editor },
{ extend: "edit", editor: editor },
]
} );
} );
I've tried django-datatables-editor library, but still cannot make it work. I've tried setting up create fuctions in ViewSet, but to no avail. In case of many-to-many relations how does DRF know which table does it need to enter data into? Do I need to explicitly specify, or does it go to model reference first and follows the M2M from there. Sorry I'm really new to DRF.
Thank you in advance!
Answers
Hi,
I'm afraid I can't help you with the Django part of it as that isn't written by me and I have no knowledge of Django in general - but I can hopefully help with the client-side part and what the client sends to the server and expects back in turn.
The first part is to check if the
api/companies.json
route expects POST parameters as described here? This might be one that you need to ask the django-datatables-editor library author I'm afraid.Allan
Hi!
Thank you for your quick response!
I guess that is a django related question.
My API says this route accepts POST request and I've also checked with
api/companies/
but the result is the sameI've dug a little deeper, and the error is not related to many-to-many field (sorry). I've removed it and error presist.
Apparently, "This field is required" is a django 'empty' validator error. It thinks that I'm trying to submit an empty field. It also checks for default values and as soon as I set the default value for the field It accepted my entry with no error, but set default value. I will look further, I'm not yet sure why it thinks the field is empty. The payload seems to say otherwise.
I'd be interesting to know what you find out please . Equally, if you have any questions about what the client-side is doing, just shoot them through.
Allan
Hey!
So I think the issue as you've pointed out was with the POST method. I didn't get to figure out a way with my the outlined setup so I simply went back to using the django-datatalbes-editor library and as soon as I've switched from ModelViewSet to DatatablesEditorModelViewSet it started accepting my create and edit entries for normal fields.
I'm still unable to figure out a Many-to-Many field create and edit though.
I've tried several approaches, but they throw various errors.
Datatalbes are rendering fine, I'm able to view the nested data, but Editor is a bit of a difficulty.
With my initial setup it gave me this error:
"Expected a list of items but got type "str"."
I tried to play around with the
field.name
option, but couldnt figure out a way. It is either that or for example with:{...
type: "select",
multiple: true
...}
I was hoping it would send it as a list but it changed to:
"Expected a list of items but got type "dict"."
I've tried switching from having serializer within a serializer and going with a "depth=1" method in Meta options in a single serializer, as per the Django Rest Framework manual and with that my JSON structure did not change, but submitting then throws:
"The following fields are present in the request, but they are not writable: type"
I've tried many other options again with
field.name
, but no bueno.Sorry if this are really basic questions:
Is there a way to pass a list of items on submit? Or do I need to find a different way to structure my JSON for example nesting objects instead of arrays like in your example: https://editor.datatables.net/examples/advanced/deepObjects.html
With a few tweaks, I was able to change my JSON to another format.
In case anybody will follow my steps I changed my serializer to:
This changed my JSON format, but gave the same error as depth = 1 option: fields not writable.
Then I also tried serialize "type = serializers.PrimaryKeyRelatedField" with a separate create method
But with the same result.
Finally I went back to my original setup and tried to play with select field options (https://editor.datatables.net/reference/field/select), but couldn't figure out a way to pass a list. At the moment I'm stuck with
{type: {non_field_errors: ["Expected a list of items but got type "str"."]}.
I'm sure this is something trivial, but I really can't think of any other way to advance.
Hi,
What do you need to pass to the server in order to have it create a list (rather than a dictionary or a string)?
Allan