Django(Model)表单域:具有键值对的Manytomany [英] Django (Model)Form Field: Manytomany with key value pair

查看:94
本文介绍了Django(Model)表单域:具有键值对的Manytomany的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一种情况,我需要做一些类似于在表单集中呈现一个表单的事情。但是,我宁愿在跳到一个解决方案之前关注这个问题。



英文第一:




  • 我正在从仓库创建货物。

  • 每个货件可以包含多个行(product_type和package_type的独特组合)以及item_count

  • 但是,对于每行,可能会有多个Packages - 一个具有item_count的product_type的package_type。

  • 客户只想看到每个product_type / package_type

  • 的一行,但是我们需要拉出股票,并正确归属每批批次的特定单位,使股票控制,召回控制等功能。因此,派遣工作人员对正在运送的包裹感兴趣。

  • 添加到此销售人员输入仅指定product_type / package_type的SalesOrder。他们对Packages也不感兴趣。 (想想下个月的转发订单 - 谁知道现在的股票呢?)。



现在的模型为了清楚):

 类包(models.Model):
create_date = models.DateField()
quantity = models.FloatField()
package_type = models.ForeignKey(PackageType,on_delete = models.PROTECT)
product_type = models.ForeignKey(ProductType,on_delete = models.PROTECT)

class CheckOut(models.Model):
package = models.ForeignKey(Package,on_delete = models.PROTECT)
create_date = models.DateField()
quantity = models.FloatField()

class Shipment(models.Model):
sales_order = models.ForeignKey(SalesOrder,null = True,blank = True)
ship_date = models.DateField(default = date。今天,
verbose_name ='发货日期')

class ShipmentLine(models.Model):
shipping = models.ForeignKey(Shipment,null = True,blank = True)
sales_order_line = models.ForeignKey(SalesOrderLine,null = True,blank = True)
quantity = models.FloatField(verbose_name ='Quantity Shipped')
checkout = models.ManytoManyField(CheckOut)

我目前使用了CheckOut:ShipmentLine的1:M关系的约束功能。然而,当将它改为M:M时,事情就会变得形式化。
在1:M版本中,装运表单(加上装运线的格式)如下所示:

  class CreateShipmentForm (forms.ModelForm):
class Meta:
model = om.Shipment

contact = forms.ModelChoiceField(
queryset = om.Contact.objects.filter iscustomer = True,active = True),
label ='Customer')
customer_ref = forms.CharField(required = False,label ='Customer Reference')
sales_order = forms.ModelChoiceField queryset = om.SalesOrder.objects.all(),
required = False,widget = forms.HiddenInput())
number = forms.CharField(label ='Shipment Number',required = False,
widget = forms.TextInput(attrs = {'readonly':'readonly'}))

class CreateShipmentLineForm(forms.ModelForm):
class Meta:
model = om.ShipmentLine
widgets = {
'checkout':forms.HiddenInput()
}
fields =('

id = forms.IntegerField(widget = forms.HiddenInput())
sales_order_line = forms.ModelChoiceField(
widget = forms.HiddenInput(),required = False,
queryset = om.SalesOrderLine.objects.all())
package = forms.ModelChoiceField(required = True ,queryset = None)#queryset填入__init__,为了简洁而被删除

所以对于1:M,我可以选择一个包,设置数量并完成。
对于M:M,我将需要选择product_type,package_type,然后选择一个或多个包,并为每个包选择一个数量。 (我将使用JS格式过滤这些)



在我的脑海里,我有几种可能性:




  • 为包和数量创建一个(子)表单,并包含在(父)表单集的每一行中

  • 字段,多值矩阵自定义表单字段,并使用

  • 构造一个模态对话框,其中M:M的东西发生,并以某种方式将结果保存到验证,保存发生的形式。 li>


我希望我已经正确和清楚地解释了。这是Django表单遇到的最复杂的应用程序,我不知道每个选项的限制/优缺点是什么。



有没有人遇到过这种情况有解决吗?或者任何对智者的话?



我提前感谢,



Nathan

$ b $我有一个类似的情况,我正在做一些像你的第二个和第三个选项:
我已经覆盖了 __ init __( ),在调用 super 之后,我有一个循环为每个字段添加一个值选择器(当然你可以在这里使用一个自定义元素)
然后重写 save()并调用 super 后,我处理额外的字段添加所有的值。


I have a situation where I need to do something similar to rendering a formset within a formset. But I'd rather focus on the problem before jumping to a solution.

In English first:

  • I'm creating a shipment from a warehouse.
  • Each shipment can contain multiple lines (unique combinations of product_type and package_type) with an item_count
  • However for each line there could be multiple "Packages" - a package_type of a product_type that has an item_count. Think of this as a batch.
  • The customer is only interested in seeing one line for each product_type/package_type
  • But we need to pull out the stock and correctly attribute the particular units from each batch to allow stock control, recall control etc to function. Therefore the dispatch staff IS interested in exactly which Packages are shipped.
  • Add to this the sales staff enter a SalesOrder that only specifies the product_type/package_type. They aren't interested in the Packages either. (Think putting in a forward order for next month - who knows what will be in stock then?).

Now the models (simplified for clarity):

class Package(models.Model):
    create_date = models.DateField()
    quantity = models.FloatField()
    package_type = models.ForeignKey(PackageType, on_delete=models.PROTECT)
    product_type = models.ForeignKey(ProductType, on_delete=models.PROTECT)

class CheckOut(models.Model):
    package = models.ForeignKey(Package, on_delete=models.PROTECT)
    create_date = models.DateField()
    quantity = models.FloatField()

class Shipment(models.Model):
    sales_order = models.ForeignKey(SalesOrder, null=True, blank=True)
    ship_date = models.DateField(default=date.today,
        verbose_name='Ship Date') 

class ShipmentLine(models.Model):
    shipment = models.ForeignKey(Shipment, null=True, blank=True)
    sales_order_line = models.ForeignKey(SalesOrderLine, null=True, blank=True)
    quantity = models.FloatField(verbose_name='Quantity Shipped')
    checkout = models.ManytoManyField(CheckOut)

I currently have it working well with the constraint of a 1:M relationship of CheckOut:ShipmentLine. However when changing this to a M:M, things get knarly form-wise. In the 1:M version the Shipment form (plus formset for the ShipmentLines) looks like this:

class CreateShipmentForm(forms.ModelForm):
    class Meta:
        model = om.Shipment

    contact = forms.ModelChoiceField(
        queryset=om.Contact.objects.filter(is_customer=True, active=True),
        label='Customer')
    customer_ref = forms.CharField(required=False, label='Customer Reference')
    sales_order = forms.ModelChoiceField(queryset=om.SalesOrder.objects.all(),
        required=False, widget=forms.HiddenInput())
    number = forms.CharField(label='Shipment Number', required=False,
        widget=forms.TextInput(attrs={'readonly': 'readonly'}))

class CreateShipmentLineForm(forms.ModelForm):
    class Meta:
        model = om.ShipmentLine
        widgets = {
            'checkout': forms.HiddenInput()
        }
    fields = ('package', 'quantity', 'id',
        'sales_order_line', 'checkout')

    id = forms.IntegerField(widget=forms.HiddenInput())
    sales_order_line = forms.ModelChoiceField(
        widget=forms.HiddenInput(), required=False,
        queryset=om.SalesOrderLine.objects.all())
    package = forms.ModelChoiceField(required=True, queryset=None)  # queryset populated in __init__, removed for brevity

So for the 1:M, I could select a package, set the quantity and done. For M:M, I will need to select product_type, package_type, and then 1 or more packages, AND for each package a quantity. (I'll be using JS in the form to filter these)

In my mind's eye I have a few possibilities:

  • create a (child) formset for the Packages and quantities and include in each line of the (parent) formset
  • create some sort of multi-field, multi-value matrix custom form field and use that
  • construct a modal dialog where the M:M stuff happens and somehow save the result to the form where validation, saving happens.

I hope I have explained it correctly and clearly enough. It's the most complex application of Django forms I've encountered and I'm not sure what the limitations/pros/cons of each of my options is.

Has anyone encountered this situation and have a solution? Or any words to the wise?

My thanks in advance,

Nathan

解决方案

I have a similar situation, I am doing something like your second and third options: I have overridden __init__() and, after calling super, I have a loop that adds a value selector for every field (of course you could use a single custom element here) Then override save() and after calling super I process the extra field adding all the values.

这篇关于Django(Model)表单域:具有键值对的Manytomany的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆