使用反向关系使用CreateView预先填充Django表单

时间:2020-09-03 13:43:05

标签: python django forms leaflet foreign-keys

我已经搜索了论坛和其他地方,但找不到我想要的东西。我有五个模型:消防栓仪表资产类型 WorkOrderActivity 工作订单

# models.py

class Hydrant(models.Model):
    uniqueId = GISModel.CharField(max_length=100)
    geom = GISModel.PointField()

    def__str__(self):
        return self.uniqueId

class Meter(models.Model):
    uniqueId = GISModel.CharField(max_length=100)
    geom = GISModel.PointField()

    def__str__(self):
        return self.uniqueId


class AssetType(models.Model):
    typeChoices = (
        ('Hydrant', 'Hydrant'),
        ('Meter', 'Meter'),
        etc...
    )
    name = models.CharField('Asset Type',max_length=30,choices=typeChoices)

    def __str__(self):
        return self.name


class WorkOrderActivity(models.Model):
    assetType = models.ForeignKey(
        'AssetType',
        related_name='workorderactivities',
        on_delete=models.SET_NULL,
        blank=True,
        null=True
    )
    activityChoices = (
        ('Paint Hydrant', 'Paint Hydrant'),
        ('Flush Hydrant', 'Flush Hydrant'),
        ('Read Meter', 'Read Meter'),
        etc...
    )
    activityType = models.CharField('Activity Type', choices=activityChoices ,max_length=50)

    def __str__(self):
        return self.activityType

class Workorder(models.Model):
    assetType = models.ForeignKey(AssetType, related_name='typeOfAsset', on_delete=models.SET_NULL)
    woActivity = models.ForeignKey(WorkOrderActivity, on_delete=models.SET_NULL)
    hydrant = models.ForeignKey(Hydrant, related_name='workorders', on_delete=models.SET_NULL)
    meter = models.ForeignKey(Meter, related_name='workorders', on_delete=models.SET_NULL)
    description = models.TextField('Description', max_length=250, blank=True, null=True)

    def __str__(self):
        return self.description

我想做的是从一张传单地图中查看所有资产(消防栓和水表),单击资产以查看弹出信息,这里有一个“创建工作订单”按钮。

在我正常的“ create_workorder”视图中,用户将不会从地图上创建工作订单,我的所有下拉列表都是链接在一起的,这意味着基于所选的资产类型,用户只能看到“ woActivity”的类型该特定类型的资产。

# views.py

# normal create workorder view
def create_workorder(request):
    if request.method == 'POST':
        form = NewWorkOrderForm(request.POST)
        if form.is_valid():
            workorder = form.save(commit=False)
            workorder.save()
            return redirect('workorders:workorders')
    else:
        form = NewWorkOrderForm()
    return render(request, 'workorders/create.html', {'form': form})

############################

# forms.py

# normal create workorder form
class NewWorkOrderForm(forms.ModelForm):

    class Meta:
        model = WorkOrder
        fields = (
            'assetType',
            'hydrant',
            'meter',
            'woActivity',
            'description'
        )

        def __init__(self, *args, **kwargs):
            super(NewWorkOrderForm, self).__init__(*args, **kwargs)
            self.fields['assetType'].label = 'Asset Type'
            self.fields['woActivity'].label = 'Work Type'

这是该视图的模板

# create.html
<div class="card">
    <div class="card-header">
        <h3 class="card-title" style="font-size:26px;">Create New Work Order</h3>
        <div class="card-tools">
            <button type="button" class="btn btn-tool" data-card-widget="collapse">
                <i class="fas fa-minus"></i>
            </button>
        </div>
    </div>
    <div class="card-body">
        <form action="" method="POST" id="newWorkOrderForm" novalidate>
            {% csrf_token %}

            <!-- assetTypes -->
            <div class="form-group">
                <div class="col-6">
                    {{ form.assetType|as_crispy_field }}
                </div>
            </div>

            <!-- hydrants -->
            <div class="form-group" id="divHydrantSelect">
                <div class="col-6">
                     {{ form.hydrant|as_crispy_field }}
                </div>
            </div>   

            <!-- meters-->
            <div class="form-group" id="divMeterSelect">
                <div class="col-6">
                     {{ form.meter|as_crispy_field }}
                </div>
            </div>                            

            <!-- workOrder Activities -->
            <div class="form-group" id="divActivitySelect">
                <div class="col-6">
                    {{ form.woActivity|as_crispy_field }}
                </div>
             </div>

             <!-- workOrder description -->
                 <div class="form-group" id="divDescription">
                     <div class="col-6">
                         {{ form.description|as_crispy_field }}
                     </div>
                  </div>

             <!-- submit form -->
             <div class="form-group" id="divSubmitForm">
                 <div class="col-6">
                     <button class="btn btn-primary" type="submit" value="Submit">Submit</button>
                 </div>
             </div>

         </form>
     </div>
 </div>

<script>
    $("#id_assetType").change(function () {
        if ($(this).val() == "---------") {
            $('#divHydrantSelect').hide();
            $('#divMeterSelect').hide();
            $('#divActivitySelect').hide();
            $('#divDescription').hide();
            $('#divSubmitForm').hide();
        } else if ($(this).val() == "1") { // hydrant
            $('#divHydrantSelect').show();
            $('#divMeterSelect').hide();
            $('#divActivitySelect').show();
            $('#divDescription').show();
            $('#divSubmitForm').show();
        } else if ($(this).val() == "2") { // meter
            $('#divHydrantSelect').hide();
            $('#divActivitySelect').show();
            $('#divDescription').show();
            $('#divSubmitForm').show();
        } else {
            $('#divHydrantSelect').hide();
            $('#divMeterSelect').hide();
            $('#divActivitySelect').hide();
            $('#divDescription').hide();
            $('#divSubmitForm').hide();
        }
        var activitiesURL = "http://localhost:8000/dashboard/workorders/ajax/load-activities/";
        var assetTypeId = $(this).val();

        $.ajax({
            url: activitiesURL,
            data: {
                "assetType": assetTypeId,
            },
            success: function (data) {  // data is the return of the load_workOrderActivity
                $("#id_woActivity").html(data);
            }
        });

        // load hydrants
        var hydrantsURL = "http://localhost:8000/dashboard/workorders/ajax/load-hydrants/";
        var hydrantId = $(this).val();
        $.ajax({
            url: hydrantsURL,
            data: {
                "hydrants": hydrantId,
            },
            success: function (data) {
                $("#hydrantSelect").html(data);
            }
        });

        // load meters
        var metersURL = "http://localhost:8000/dashboard/workorders/ajax/load-meters/";
        var meterId = $(this).val();
        $.ajax({
            url: metersURL,
            data: {
                "meters": meterId
            },
            success: function (data) {
                $("#meterSelect").html(data);
            }
        });

    });
    $("#id_assetType").trigger("change");
</script>

    

如果我要创建正常的工作订单,这会很好,但是在地图上这样做会遇到问题,因为我不知道如何用消火栓填充表单字段“消火栓”目的。我可以使用下面的内容自动填充“ assetType ”,然后为我选择所有消防栓,但是我希望在我填写“ 消防栓”字段时点击地图中的“创建工作订单”。

# views.py
# create workorder from the map via the popup
class CreateHydrantWOFromMap(CreateView):
    model = WorkOrder
    # fields = '__all__'
    template_name = 'workorders/createHydrantWOfromMap.html'
    form_class = NewHydrantForm
    success_url = reverse_lazy('workorders:workorders')

    def get_initial(self, *args, **kwargs):
        initial = super(CreateHydrantWOFromMap, self).get_initial(**kwargs)
        initial['assetType'] = '3'
        return initial

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super().dispatch(*args, **kwargs)

0 个答案:

没有答案