data not saving through a many to many relationship

23 views
Skip to first unread message

MikeKJ

unread,
Nov 20, 2013, 7:37:09 AM11/20/13
to django...@googlegroups.com
In the view do_advice the specialism, delivery_method and face_to_face_locations selections are not being saved into the corresponding tables
of advicelevel_specialism, advicelevel_delivery_method and advicelevel_face_to_face_locations which are the fields of advicelevel_id  and x_id where x = specialism etc, normal many to many table right?
The actual AdviceLevel table is properly saved to with the advice_id, organisation_id, the selected levels etc everytning that is not a many to many effectively

Needless it say it works perfectly in Admin, just this user facing version doesnt work

Models:
class Organisation(models.Model):
    title = models.CharField(max_length=150)
    address1 = models.CharField(max_length=150, null=True, blank=True)
    address2 = models.CharField(max_length=150, null=True, blank=True)
    place = models.CharField(max_length=150, null=True, blank=True)
    postcode = models.CharField(max_length=15, null=True, blank=True)
    tel = models.CharField(max_length=30, null=True, blank=True)
    fax = models.CharField(max_length=30, null=True, blank=True)
    email = models.EmailField(null=True, blank=True)
    web = models.URLField()
    text = models.TextField()
    advice = models.ManyToManyField(Advice, through='AdviceLevel')   // note THROUGH
    crs = models.BooleanField()
    appointment_locations = models.TextField(null=True, blank=True)
    drop_in_locations = models.TextField(null=True, blank=True)
    def __unicode__(self):
         return u"%s" % self.title
    class Meta:
        ordering = ('title',)

class AdviceLevelKey(models.Model):
    key_level = models.CharField(max_length=150)
    key_level_text = models.TextField()
    key_level_cab = models.CharField(max_length=15)
    def __unicode__(self):
        return self.key_level

class AdviceLevel(models.Model):
    advice = models.ForeignKey(Advice)
    organisation = models.ForeignKey(Organisation)
    level_1 = models.BooleanField()
    level_2 = models.BooleanField()
    level_3 = models.BooleanField()
    level_4 = models.BooleanField()
    specialism = models.ManyToManyField(Specialism, null=True, blank=True)
    service_restriction = models.TextField(null=True, blank=True)
    delivery_method = models.ManyToManyField(CRSDeliveryMethod, null=True, blank=True)
    face_to_face_locations = models.ManyToManyField(Location, null=True, blank=True)
    service_supervisor = models.CharField(max_length=175, null=True, blank=True)
    def __unicode__(self):
        return u"%s (%s)" % (self.organisation, self.advice)

View // the offending one

class AdviceForm(ModelForm):
    class Meta:
        model = AdviceLevel
        exclude = ('organisation',)

def do_advice(request):
    if not request.user.is_authenticated():
        return HttpResponseRedirect('/user/login/')
    this_org = request.session['this_org']
    advkey = AdviceLevelKey.objects.all()
    org = Organisation.objects.get(pk=this_org)
    orgid = org.id
    organisation = ""
    help = OrganisationHelpTexts.objects.all()
    try:
        data_set = AdviceLevel.objects.all().filter(organisation=this_org)
    except AdviceLevel.DoesNotExist:
        data_set = None

    if request.POST:
        if 'editadvice' in request.POST:
            return HttpResponseRedirect('/directory/edit_advice/')
        if 'adviceform' in request.POST:
            adviceform = AdviceForm(request.POST)               
            if adviceform.is_valid():
                organisation = org
                adv = adviceform.cleaned_data['advice']
                service_restriction = adviceform.cleaned_data['service_restriction']
                service_supervisor = adviceform.cleaned_data['service_supervisor']
                specialism = adviceform.cleaned_data['specialism']
                delivery_method = adviceform.cleaned_data['delivery_method']
                face_to_face_locations = adviceform.cleaned_data['face_to_face_locations']
                level_1 = adviceform.cleaned_data['level_1']
                level_2 = adviceform.cleaned_data['level_2']
                level_3 = adviceform.cleaned_data['level_3']
                level_4 = adviceform.cleaned_data['level_4']
                if (level_3 == 0 and level_4 == 1) or (level_2 == 0 and (level_3 == 1 or level_4 == 1)) or (level_1 == 0 and (level_2 == 1 or level_3 == 1 or level_4 == 1)):
                    error = "That isn't a possible combination, the tiers are progressive"
                    adviceform = AdviceForm(request.POST)
                    return render_to_response('directory/advice.html', {'help': help, 'error': error, 'adviceform': adviceform, 'this_org': this_org, 'advkey': advkey, 'org': org, },context_instance=RequestContext(request))
                else:
                    af = adviceform.save(commit=False)
                    af.organisation = organisation
                    af.save()
                    adviceform = AdviceForm()
            else:
                adviceform = AdviceForm(request.POST)
    else:
        adviceform = AdviceForm()
    if data_set:
        adviceform = AdviceForm()
        return render_to_response('directory/advice.html', {'help': help, 'adviceform': adviceform, 'this_org': this_org, 'data_set': data_set, 'advkey': advkey, 'org':org, }, context_instance=RequestContext(request))
    else:
        return render_to_response('directory/advice.html', {'help': help, 'adviceform': adviceform, 'this_org': this_org, 'advkey': advkey, 'org': org,}, context_instance=RequestContext(request))







MikeKJ

unread,
Nov 20, 2013, 7:54:23 AM11/20/13
to django...@googlegroups.com
Decided that the relationship  advice = models.ManyToManyField(Advice, through='AdviceLevel') in the Organsiation model is redundant and removed it but it hasn;t made any difference to the now NON intermdiate model AdviceLevel


MikeKJ

unread,
Nov 20, 2013, 11:41:57 AM11/20/13
to django...@googlegroups.com
Update:

So editing AdviceLevel with

def edit_advice(request):

    if not request.user.is_authenticated():
        return HttpResponseRedirect('/user/login/')
    this_advice = request.POST.get('advice_id')
    sp = Specialism.objects.all().filter(advicelevel=this_advice)
    de = CRSDeliveryMethod.objects.all().filter(advicelevel=this_advice)
    lo = Location.objects.all().filter(advicelevel=this_advice)
    help = OrganisationHelpTexts.objects.all()
    advice = request.POST.get('advice')
 #   adv = Advice.objects.get(title=advice)
 #   id_adv = adv.id
    this_org = request.session['this_org']
    this = Organisation.objects.get(pk=this_org)
    id_org = this.id
    thisadvlvl = AdviceLevel.objects.get(pk=this_advice)
    level_1 = thisadvlvl.level_1
    level_2 = thisadvlvl.level_2
    level_3 = thisadvlvl.level_3
    level_4 = thisadvlvl.level_4

    advkey = AdviceLevelKey.objects.all()
    if request.POST:
    #    raise NameError(request.POST)
        if 'adviceid' in request.POST:
            return HttpResponseRedirect('/directory/delete_advice/')
        if 'editform' in request.POST:
            editform = EditAdviceLevelForm(request.POST, instance=thisadvlvl)
            if editform.is_valid():
                error = ""
                level_1 = editform.cleaned_data['level_1']
                level_2 = editform.cleaned_data['level_2']
                level_3 = editform.cleaned_data['level_3']
                level_4 = editform.cleaned_data['level_4']
                service_restriction = editform.cleaned_data['service_restriction']
                service_supervisor = editform.cleaned_data['service_supervisor']
                specialism = editform.cleaned_data['specialism']
                delivery_method = editform.cleaned_data['delivery_method']
                face_to_face_locations = editform.cleaned_data['face_to_face_locations']

                if (level_3 == 0 and level_4 == 1) or (level_2 == 0 and (level_3 == 1 or level_4 == 1)) or (level_1 == 0 and (level_2 == 1 or level_3 == 1 or level_4 == 1)):
                    error = "That isn't a possible combination, the tiers are progressive"
                    editform = EditAdviceLevelForm(request.POST, instance=thisadvlvl)
                    return render_to_response('directory/edit_advice.html', {'thisadvlvl': thisadvlvl, 'help': help, 'sp': sp, 'lo': lo, 'de': de, 'advice': advice, 'advkey': advkey, 'editform': editform, 'level_1': level_1, 'level_2': level_2, 'level_3': level_3, 'level_4': level_4, 'this_advice': this_advice, 'error': error, },context_instance=RequestContext(request))
                editform.save()
                return HttpResponseRedirect('/directory/do_advice/')

        else:
            editform = EditAdviceLevelForm(request.POST, instance=thisadvlvl)
    else:
        editform = EditAdviceLevelForm(instance=thisadvlvl)
    return render_to_response('directory/edit_advice.html', {'thisadvlvl': thisadvlvl, 'help': help, 'sp': sp, 'lo': lo, 'de': de, 'advice': advice, 'advkey': advkey, 'editform': editform, 'level_1': level_1, 'level_2': level_2, 'level_3': level_3, 'level_4': level_4, 'this_advice': this_advice, },context_instance=RequestContext(request))

works both adding or deleting a many to many related field so the difference is in the save methods
editform.save() in this working case and
af = adviceform.save(commit=False)
af.organisation = organisation
af.save()
which doesn't

Now I deliberately used commit = False because I wanted to prepopulate the organisation rather than have the user select(again) the organisation so I therefore had to add the value of organisation to the form save hence using commit=False, unless someone can spot an error somewhere that is causing the problem or knows of a differnt way of accomplishing what commit does.  Cannot just save the form as adviceform.save() because organisation MUST have a value see the Organisation model.
Any ideas?


Reply all
Reply to author
Forward
0 new messages