代码之家  ›  专栏  ›  技术社区  ›  amol rane

如何编辑具有单个或多个多选字段的窗体

  •  0
  • amol rane  · 技术社区  · 5 年前
    I have a form with MultipleChoiceField. I am able to save the data correctly. Now, if a user wants to edit that form he/she should see already selected items in the dropdown along with remaining all the other option. I want this as a function-based view. eg. I have 5 products in the dropdown and at the time of form submission, I selected products 1 and 2. Now, when I click on edit I should be able to see products 1 and 2 selected along with the other 3 products as unselected.Just help me with the edit view of this form. I am using same template for create and update. the code is messy.
    

    型号.py

        class Lead(models.Model):
            state = models.CharField(_("State"), max_length=255, blank=True, null=True)
            type = models.CharField(max_length=20,choices=TYPE,blank=True,null=True)
            products = models.ManyToManyField(Product,related_name='company_products',limit_choices_to=5,blank=True,null=True)
    

    表单.py我的自定义表单只是共享产品部分,因为代码越来越大。

        class LeadForm(forms.ModelForm):
            product_queryset = []
            products = forms.MultipleChoiceField(choices=product_queryset)
    
            def __init__(self, *args, **kwargs):
                assigned_users = kwargs.pop('assigned_to', [])
                super(LeadForm, self).__init__(*args, **kwargs)
                self.fields['products'].required = False
                self.fields['products'].choices = [(pro.get('id'),pro.get('name')) for pro in Product.objects.all().values('id','name')]
    

    视图.py我只是分享产品部分的代码有点长。

        def update_lead(request, pk):
            lead_record = Lead.objects.filter(pk=pk).first()
            template_name = "create_lead.html"
            users = []
            if request.user.role == 'ADMIN' or request.user.is_superuser:
                users = User.objects.filter(is_active=True).order_by('email')
            else:
                users = User.objects.filter(role='ADMIN').order_by('email')
            status = request.GET.get('status', None)
            initial = {}
            if status and status == "converted":
                error = "This field is required."
                lead_record.status = "converted"
                initial.update({
                    "status": status, "lead": lead_record.id})
            error = ""
            form=LeadForm(instance=lead_record,initial=initial,assigned_to=users)
            if request.POST:
                form = LeadForm(request.POST, request.FILES,
                                instance=lead_record,
                                initial=initial, assigned_to=users)
    
    
                if form.is_valid():               
                    if request.POST.getlist('products', []):
                        lead_obj.products.clear()
                        lead_obj.products.add(*request.POST.getlist('products'))
                    else:
                        lead_obj.products.clear()                  
                    status = request.GET.get('status', None)
                    success_url = reverse('leads:list')
                    if status:
                        success_url = reverse('accounts:list')
                    return JsonResponse({'error': False, 'success_url': success_url})
                return JsonResponse({'error': True, 'errors': form.errors})
            context = {}
            context["lead_obj"] = lead_record
            context["lead_form"] = form
            context["teams"] = Teams.objects.all()
            context['products'] = Product.objects.all()
            context["assignedto_list"] = [
                int(i) for i in request.POST.getlist('assigned_to', []) if i]
            return render(request, template_name, context)
    

                    <div class="form-group" style="height:20px;">
                       <label for="exampleInputEmail1">Product{% if products.field %}<span
                            class="error">*</span>{% endif %}</label>
                        <select multiple="multiple">
    
                          {% for product in products %}
                          <option value="{{product.pk}}" {% if product in products.company_products.all %} selected="" {% endif %}>{{product.name}}</option>
                          {% endfor %}
                      </select>
    
                      </div>
    
    1 回复  |  直到 5 年前
        1
  •  0
  •   dani herrera    5 年前

    在模板上,应该避免“手工”渲染窗体。您应该使用 django forms rendering system

    <form action="/your-name/" method="post">
        {% csrf_token %}
        {{ lead_form }}
        <input type="submit" value="Submit">
    </form>
    

    如果需要渲染 just this field manually

            <div class="form-group" style="height:20px;">
               <label for="exampleInputEmail1">Product{% if products.field %}<span
                    class="error">*</span>{% endif %}</label>
    
               {{ lead_form.products }}
    
              </div>