Django and ModelMultipleChoiceField forms when working with existing records

I am trying to do something that, in my opinion, is quite common, but I'm just not sure how to handle this.

What I am doing now: I am currently creating a list of checkboxes (using "CheckboxSelectMultiple") in my form, which automatically checks off all users included in the "members" from the list of all users in django (created by "queryset = User.objects.all ( ) ").

What I really want to do: I do not want to list each user in Django, I just want to show a list of users in "members".

How can I do this: I think I can do this by changing the value of the query set as "project.members.all ()", where project = Project (a specific instance of the project). But how to convey this context to my form?

# models.py class Project(models.Model): name = models.CharField(max_length=100) members = models.ManyToManyField(User, related_name="members", blank=True, null=True) # forms.py class ProjectSettings(forms.Form): summary = forms.CharField(max_length=200) members = forms.ModelMultipleChoiceField(queryset=User.objects.all(), widget=forms.CheckboxSelectMultiple()) #template snippet <form method="post" action="/projects/{{ project.slug }}/settings/save/"> {% for field in form %} <div class="form-row"> {{ field.errors }} {{ field.label_tag }} {{ field }} {% if field.help_text %} <p class="help-text">{{ field.help_text }}</p> {% endif %} </div> {% endfor %} # view.py def update_project(request, project_slug): if request.method == 'POST': form = ProjectSettings(request.POST) if form.is_valid(): # All validation rules pass # Process the data in form.cleaned_data project.summary = form.cleaned_data['summary'] project.members = form.cleaned_data['members'] project.save() return HttpResponseRedirect('/projects/' + project.slug + '/') else: data_dict = {'summary': project.summary, 'members': project.members.all()} form = ProjectSettings(initial=data_dict) return render_to_response('update_project.html', {'form': form}, context_instance=RequestContext(request)) 

I hope this makes sense, and I apologize because I really think it is something simple, I am not here, but I could not find a specific example showing how to do this with non-model forms.

Thanks in advance,

Jamie

+4
source share
1 answer

I assume that you are leaving some things out of your project model. Your view also calls project.members.all() and project.summary without getting the project in an else statement.

Assuming you have a summary field in the project model, if you want to use a form, not a model, then:

forms.py

 class ProjectSettings(forms.Form): summary = forms.CharField(max_length=200) def __init__(self, qs=None, *args, **kwargs): super(ProjectSettings, self).__init__(*args, **kwargs) if qs: self.fields['members'] = forms.ModelMultipleChoiceField(queryset=qs, widget=forms.CheckboxSelectMultiple()) 

and in your views.py you will go in qs to the form:

 def update_project(request, project_slug): project = None if project_slug: project = get_object_or_404(Project, name=project_slug) # somehow get your project object qs = project.members.all() if request.method == 'POST': form = ProjectSettings(qs, request.POST) if form.is_valid(): # All validation rules pass # Process the data in form.cleaned_data project.summary = form.cleaned_data['summary'] project.members = form.cleaned_data['members'] project.save() return HttpResponseRedirect('/projects/' + project.slug + '/') else: form = ProjectSettings(qs) return render_to_response('update_project.html', {'form': form}, context_instance=RequestContext(request)) 

Using ModelForm makes sense here if you really have a summary field in your Project model.

forms.py:

 class ProjectSettings(forms.ModelForm): def __init__(self, qs=None, *args, **kwargs): super(ProjectSettings, self).__init__(*args, **kwargs) self.fields['members'].widget = forms.CheckboxSelectMultiple() class Meta: model = Project fields = ('summary', 'members') 

views.py:

 def update_project(request, project_slug): project = None if project_slug: project = get_object_or_404(Project, name=project_slug) # somehow get your project object if request.method == 'POST': form = ProjectSettings(request.POST, instance=project) if form.is_valid(): # All validation rules pass # Process the data in form.cleaned_data project.save() return HttpResponseRedirect('/projects/' + project.slug + '/') else: form = ProjectSettings(instance=project) return render_to_response('update_project.html', {'form': form}, context_instance=RequestContext(request)) 
+9
source

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


All Articles