django - 如何编辑具有单个或多个 MultichoiceFields 的表单
问题描述
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)
forms.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')]
views.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)
create_lead.html 我正在使用这个 html 来创建和更新视图。我只是在分享产品 div 部分
<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>
解决方案
在模板上,您应该避免“手动”渲染表单。您应该使用django 表单渲染系统来渲染表单。:
<form action="/your-name/" method="post">
{% csrf_token %}
{{ lead_form }}
<input type="submit" value="Submit">
</form>
如果您需要手动渲染此字段:
<div class="form-group" style="height:20px;">
<label for="exampleInputEmail1">Product{% if products.field %}<span
class="error">*</span>{% endif %}</label>
{{ lead_form.products }}
</div>
推荐阅读
- google-apps-script - 使用 REST API 向 Google Chat 发送消息(Google 示例在 2020 年不起作用)
- angular - 从本地目录读取 csv 文件
- python - 为什么使用 Conda 虚拟环境时回溯不引用 Python 文件?
- ffmpeg - ffmpeg:无法将硬件编码器 h264_rkmpp 与软件解码的 ATSC OTA 传输一起使用
- ios - 使用 beginUpdates 重新加载 tableView 部分
- mysql - 在关系链接 Laravel 中调用枢轴模型方法
- python - 在 Docker 容器内 - python: 无法打开文件 './services/web/manage.py': [Errno 2] 没有这样的文件或目录
- sql - 根据标题将值相加
- c# - 按 Count 然后按字符串排序排序的字符串集列表
- c# - ASP.Net/C# 如何存储方法字符串返回以供以后在另一个方法中使用?