Limit the options available in a Django form set

I have a set of forms that has a “Commands” field that should be limited to the commands the current user belongs to.

def edit_scrapbook(request): u=request.user ScrapbookAjaxForm = modelformset_factory(Scrapbook, fields= ('description','status','team')) choices=False for t in u.team_set.all(): if choices: choices=choices,(t.id,t.name) else: choices=choices,(t.id,t.name) if request.method == 'POST': formset = ScrapbookAjaxForm(request.POST, queryset=Scrapbook.objects.filter(owner=u)) if formset.is_valid(): instances=formset.save(commit=False) for i in instances: i.owner=request.user i.save() formset.save_m2m() return HttpResponseRedirect(reverse('scrapbooks.views.index')) else: formset = ScrapbookAjaxForm(queryset=Scrapbook.objects.filter(owner=u)) for form in forms: for field in form: if field.label == 'Team': field.choices=choices c=RequestContext(request) return render_to_response('scrapbooks/ajax_edit.html', {'fs':formset},context_instance=c) 

This does not affect the choice in the form at all. This is pretty ugly and probably the result of looking at this issue for too long. I also tried using a custom form set, but I can't get the custom form set to accept this parameter.

How do I limit the selection of the Team field in my subquery in a form set based on the commands that the user is in?

0
source share
2 answers

From the django model documentation :

Finally, note that the selection can be any iterable object — optionally a list or tuple. This allows you to build your choice dynamically. But if you find you yourself choose dynamic hacking options, you are probably better off using the appropriate database table with a foreign key. The choice is for static data that does not change much, if ever.

I would use the same idea then: on the form, you use ForeignKey for the command, and then you can limit this list to some query.

Some additional suggestions:

  • Use the ForeignKey command for the command
  • Define your own ModelChoiceField with a query that will restrict its contents based on the parameter specified in its initialization.
  • override the default field type to use the native ModelChoiceField. Note that you must pass the filter for the command to initialize your ModelChoiceField.
+1
source

Not sure if this is causing the problem, but there is a big problem with how you create the selection tuple.

After four commands, the selection will look like this:

 ((((False, (1, u'Team 1')), (2L, u'Team 2')), (3, u'Team 3')), (4, u'Team 4')) 

which is obviously not valid for setting a select box. The best way to do this would be to use list comprehension instead of the whole loop:

 choices = [(t.id,t.name) for t in u.team_set.all()] 
0
source

Source: https://habr.com/ru/post/897041/


All Articles