question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ModelForm : pass the object's id as extra parameter in AJAX call

See original GitHub issue

Hi !

I have a Team model and a Member model. The Team model has a captain field.

Now, in my ModelForm, for the captain field, I want to filter the autocomplete to show only members of the team that I’m editing. This means I need to pass a team_id parameter alongside the q parameter.

I think it’s a fairly commun scenario, just like forward=['continent']. I googled the issue and found some links, but they all are quite complex hacks combining advanced django and javascript, and I couldn’t make them work (I’m no javascript expert).

I’d suggest either :

  • add an option like forward but to send the modelform’s instance’s pk instead
  • document the easiest way to get that result

Thanks a lot for the awesome module !

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:15 (11 by maintainers)

github_iconTop GitHub Comments

1reaction
toudicommented, May 16, 2016

Ok, chaps, sorry for the long delay, I couldn’t get to the computer.

Anyways, I think this turned out to be pretty easy problem (or am I this naive?). Here it goes:

# the models:
class Team(models.Model):
    name = models.CharField(max_length=255)
    captain = models.OneToOneField(
        'team.TeamMember',
        related_name='+',
        null=True,
        blank=True
    )

    def __unicode__(self):
        return self.name


class TeamMember(models.Model):
    team = models.ForeignKey('team.Team')
    name = models.CharField(max_length=32)

    def __unicode__(self):
        return '%s/%s' % (self.team.name, self.name)

# the forms:
from django import forms
from team.models import Team
from dal import autocomplete


class TeamForm(forms.ModelForm):
    team_id = forms.IntegerField(
        required=False, widget=forms.HiddenInput)

    def __init__(self, *args, **kwargs):
        instance = kwargs.get('instance', None)
        if instance:
            kwargs['initial'] = {'team_id': instance.pk}

        super(TeamForm, self).__init__(*args, **kwargs)

    class Meta:
        model = Team
        widgets = {
            'captain': autocomplete.ModelSelect2(
                url='team-member-autocomplete',
                forward=['team_id']
            )
        }
        exclude = []

    def clean_captain(self):
        captain = self.cleaned_data.get('captain')

        if captain and captain.team_id != self.instance.id:
            raise forms.ValidationError("Invalid captain for this team!")

        return captain

# the views
from dal import autocomplete
from team.models import TeamMember


class TeamMemverAutocomplete(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        # Don't forget to filter out results depending on the visitor !

        team_id = self.forwarded['team_id']

        if not team_id:
            return TeamMember.objects.none()

        qs = TeamMember.objects.filter(team_id=team_id)

        if self.q:
            qs = qs.filter(name__icontains=self.q)

        return qs

# the admin:
from django.contrib import admin
from team.models import Team, TeamMember
from team.forms import TeamForm


class TeamAdmin(admin.ModelAdmin):
    form = TeamForm


admin.site.register(Team, TeamAdmin)
admin.site.register(TeamMember)

I don’t know if this is the desired result for @olivierdalang , however this works in the following way:

  1. It autocompletes the captain based on selected team ID
  2. It only does so if a team is being edited (no results will be given on team creation)
  3. Even if somebody manages to change the team id, validationerror is thrown.

yours truly,

1reaction
toudicommented, May 13, 2016

this looks like an interesting problem. I’ll try tackling it, probably during the night.

cheers, m.

Read more comments on GitHub >

github_iconTop Results From Across the Web

django: passing data via ajax to views, and then into forms for ...
It seems you already use 'form', then what I did is: views.py: if request.method == "POST": form = MyForm(request.
Read more >
How to Work with AJAX in Django - Pluralsight
To make the guide more interactive, we will use a real-time example to demonstrate the POST and GET AJAX requests in Django.
Read more >
How to send Django form with AJAX - DEV Community ‍ ‍
To create and save an object in a single step, we are using the create() method. Let's take a look our html form...
Read more >
Send the data with a POST request with an inlineformset ...
In principle I have two forms in a createview (ModelForm and ... action: function () { $.ajax({ url: url, type: 'POST', data: parameters, ......
Read more >
Django forms with Ajax | How to use ajax with django - YouTube
If you want to see a jquery version, below is the link to the like ... ajax request, django ajax post, django ajax...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found