user1170793
user1170793

Reputation: 220

Checking for object existence with same m2m relation in django?

I have a model Teacher like this:

name = models.CharField(max_length=100,unique=True)
course = models.ManyToManyField(Course)

And Course model:

course_name = models.CharField(max_length=100,unique=True)

While creating Teacher object I want to make sure that the new object I am creating should not have same courses(m2m relation) with any other existing Teacher object.

For example if Teacher object A has English,Maths,History m2m Course relation, So no new Teacher object can have English,Maths,History.

View

def AddTeacher(request):
    #id's are the courses object id
    id1 = request.POST.get('id1')
    id2 = request.POST.get('id2')
    id3 = request.POST.get('id3')


    Tobject  = Teacher(name="temp")
    Tobject.save()

    for i in [id1,id2,id3]:
        Cobject = Course.objects.get(id=i)
        Tobject.course.add(Cobject )
    Tobject.name = "Teacher"+str(Tobject.id)
    Tobject.save()

    temp = {}
    temp['message'] = "Object created successfully"
    return HttpResponse(json.dumps(temp),mimetype="application/json")

Upvotes: 1

Views: 446

Answers (3)

Guillermo Siliceo Trueba
Guillermo Siliceo Trueba

Reputation: 4629

In a related answer but not exactly for this case, you can check if an object is in a m2m with:

if english_course in teacher.courses.all():
    # already in there :)

I just thought it was a nice way to do it.

Upvotes: 0

Mikael
Mikael

Reputation: 3234

OK here it goes

def AddTeacher(request):
    #id's are the courses object id
    id1 = request.POST.get('id1')
    id2 = request.POST.get('id2')
    id3 = request.POST.get('id3')

    qs = Teacher.objects.all()

    #Build a dynamic filter query
    qs = reduce(lambda q, c: q.filter(course=c), [c for c in [id1, id2, id3]], qs)

    if qs:
        raise ValueError("A teacher with the selected courses already exists")

    teacher  = Teacher(name="temp")
    teacher.save()

    for i in [id1, id2, id3]:
        course = Course.objects.get(id=i)
        teacher.course.add(course)
    teacher.name = "Teacher"+str(teacher.id)
    teacher.save()

    return HttpResponse(json.dumps({
        'message': 'Object created successfully'
    }), mimetype="application/json")

Upvotes: 0

supervacuo
supervacuo

Reputation: 9262

Seems relatively simple. Just do a query for a teacher with all the course IDs specified in request.POST and bail if there are any results:

def AddTeacher(request):
    #id's are the courses object id
    id1 = request.POST.get('id1')
    id2 = request.POST.get('id2')
    id3 = request.POST.get('id3')

    if Teacher.objects.filter(course=id1).filter(course=id2).filter(course=id3).count() > 0:
        return HttpResponseForbidden("Can't add a teacher with these courses; one already exists")

    # ... function continues

This addresses the precise case in your question; if you want to deal with situations where the specified courses are a sub-set of an existing teacher's courses (if you decide to allow adding a teacher with two courses, for instance) more thought will be needed.

Upvotes: 1

Related Questions