3

Im having a problem with bulk many to many relationship removing and adding.

This is the JS that sends the pk of the user to be updated and the pk of the skills that will be added to the many to many.

function attachskillls(){

var checkedValues = $('input:checkbox:checked').map(function() {
  return this.value;
}).get();

console.log(checkedValues)

data = {
  'skills' : checkedValues,
  'pk' : getUrlVars()["id"]
}
console.log(data)

$.ajax({
  type: "POST",
  url: "/api/skill/attch/",
  data: JSON.stringify(data),
  contentType: "application/json",
  dataType: "json"
})

data is packed like this

{"skills":["1","2","3"],"pk":"1"}

This is the model the skills will be related to

class Resource(models.Model):

    title = models.CharField(max_length=10)
    preferred_name = models.CharField(max_length=20)
    last_name = models.CharField(max_length=30)
    employstatus = models.CharField(max_length=20)
    employer = models.ForeignKey('Employer')
    role = models.ForeignKey('Role')
    location = models.ForeignKey('Location')
    workphone = models.CharField(max_length=25, blank=True, null=True)
    mobile_phone = models.CharField(max_length=15, blank=True, null=True)
    email = models.CharField(max_length=15, blank=True, null=True)
    notes = models.CharField(max_length=200, blank=True, null=True)
    updated_by = models.CharField(max_length=30, blank=True, null=True)
    skillset = models.ManyToManyField('ReferenceSkillList')

This is my api so far I am trying to filter resource by pk so I have the correct user to add the skills to then to clear all relationships that may already be added then to bulk add the new relationships.

def Skillattachment(request):
    body = json.loads(request.body)
    if request.method == "POST":
        pk = body['pk']
        skills = body
        res = Resource.objects.filter(pk=pk)
        res.skillset.clear()
        res.skillset.add(skills)

    else:
        search_id = ''

    return HttpResponse(json.dumps(body), content_type='application/json')

Is there a better way to do what I am trying todo?

I I currently get the error 'QuerySet' object has no attribute 'skillset' though I am unsure why? maybe I have made the M2M incorrectly but I have followed the docs

SpeedyH30
  • 89
  • 2
  • 12

1 Answers1

3

You should use res = Resource.objects.get(pk=pk) instead. filter would give you a queryset as result.

Also your variable skills is just a data structure not objects. You might need:

skills = ReferenceSkillList.objects.filter(id__in=body['skills'])
res = Resource.objects.get(pk=pk)
res.skillset.clear()
res.skillset.add(*skills)

Django docs.

Shang Wang
  • 24,909
  • 20
  • 73
  • 94
  • Would I not want it to be a list of ids as those ids are the pks of the skills I want to attach? I'm very new to this but I'm trying to stretch out, I do now get the error of int() argument must be a string or a number, not 'QuerySet' is a QuerySet not just another type of list – SpeedyH30 Dec 14 '15 at 19:33
  • 1
    Sorry I edited the answer. It's `*skills`. Look at this SO q&a: http://stackoverflow.com/questions/4979542/python-use-list-as-function-parameters – Shang Wang Dec 14 '15 at 19:36
  • Holy crap, If I could kiss you I would. I dont think I would have got the skills = ReferenceSkillList.objects.filter(id__in=body['skills']) thank you so much, If I could up vote you more I would, deffo the most helpful person I have encountered on SO so far. – SpeedyH30 Dec 14 '15 at 19:47
  • Thanks @ShangWang This answer still works on Django 2.1.5. Replace the `skills = ...filter(...)` line with `skills = ...bulk_create(...)`, so that I can create multiple items then add them to a `manytomany` field. `(*skills)` is the key point. haha – C.K. Feb 07 '19 at 01:49
  • Is it possible to do it without two database hits ? (clear() and add()/set()) – Ebram Shehata Sep 05 '20 at 08:35