如何根据编辑时的存储值显示/隐藏Django表单字段?

huangapple go评论68阅读模式
英文:

How to show/hide a django form field based on the stored value while editing?

问题

**models.py**:
```python
cv_choices = (
    ('One Time', 'One Time'),
    ('Renewal', 'Renewal'),
)

class Certification(models.Model):
    user = models.ForeignKey(Account, on_delete=models.CASCADE, null=True)
    certName = models.CharField(_('Certification Name'), max_length=100, null=True)
    certId = models.CharField(_('Certification ID'), max_length=100, null=True)
    certUrl = models.URLField(_('Certification URL'), max_length=500, null=True)
    certStartDate = models.DateField(_('Certification Start Date'), null=True)
    certEndDate = models.DateField(_('Certification End Date'), null=True, blank=True)
    certValidity = models.CharField(_('Certification Validity'), max_length=10, choices=cv_choices, default='Renewal', null=True)
    createdDate = models.DateTimeField(_('Created Date'), auto_now_add=True, editable=False)
    modifiedDate = models.DateTimeField(_('Modified Date'), auto_now=True, editable=False)

    def __str__(self):
        return self.certName

forms.py:

class CertificationForm(forms.ModelForm):
    certValidity = forms.ChoiceField(choices=[('One Time', 'One Time'), ('Renewal', 'Renewal')])

    class Meta:
        model = empCertification
        fields = ('user', 'certName', 'certId', 'certUrl', 'certStartDate', 'certEndDate', 'certValidity')

    def __init__(self, *args, **kwargs):
        super(empCertificationForm, self).__init__(*args, **kwargs)
        self.fields['user'].widget.attrs['class'] = 'form-select'
        self.fields['certName'].widget.attrs['class'] = 'form-control'
        self.fields['certId'].widget.attrs['class'] = 'form-control'
        self.fields['certUrl'].widget.attrs['class'] = 'form-control'
        self.fields['certStartDate'].widget.attrs['class'] = 'form-control'
        self.fields['certEndDate'].widget.attrs['class'] = 'form-control'
        self.fields['certValidity'].widget.attrs['class'] = 'form-select'
        for field in self.fields:
            self.fields[field].widget.attrs['placeholder'] = 'Provide Details'

Edit Template File:

<form action="{% url 'certificationEdit' certification.pk %}" method="post" class="form" enctype="multipart/form-data" novalidate>
    {% csrf_token %}
    <div class="card-body border-top p-9">
        {% if certificationForm.errors %}
            {% for field in certificationForm %}
                {% for error in field.errors %}
                    <div class="alert alert-danger">
                        <strong>{{field.name|title}} - {{error|escape}}</strong>
                    </div>
                {% endfor %}
            {% endfor %}
            {% for error in certificationForm.non_field_errors %}
                <div class="alert alert-danger">
                    <strong>{{error|escape}}</strong>
                </div>
            {% endfor %}
        {% endif %}
        <div class="row">
            <div class="col-lg-6">
                <div class="form-floating mb-7">
                    {{certificationForm.user}}
                    <label class="required">User</label>
                </div>
            </div>
            <div class="col-lg-6">
                <div class="form-floating mb-7">
                    {{certificationForm.certValidity}}
                    <label>Certification Validity</label>
                </div>
            </div>
            <div class="col-lg-6">
                <div class="form-floating mb-7">
                    {{certificationForm.certName}}
                    <label class="required">Certification Name</label>
                </div>
            </div>
            <div class="col-lg-6">
                <div class="form-floating mb-7">
                    {{certificationForm.certId}}
                    <label class="required">Certification ID</label>
                </div>
            </div>
            <div class="col-lg-6">
                <div class="form-floating mb-7">
                    {{certificationForm.certUrl}}
                    <label class="required">Certification URL</label>
                </div>
            </div>
            <div class="col-lg-6">
                <div class="form-floating mb-7">
                    {{certificationForm.certStartDate}}
                    <label class="required">Certification Start Date</label>
                </div>
            </div>
            <div class="col-lg-6 certEndDate">
                <div class="form-floating mb-7">
                    {{certificationForm.certEndDate}}
                    <label>Certification End Date</label>
                </div>
            </div>
        </div>
    </div>
    <div class="card-footer d-flex justify-content-end py-6 px-9">
        <a href="{% url 'certificationList' %}" class="btn btn-light-info me-3">Discard</a>
        <button type="submit" class="btn btn-primary">Save Changes</button>
    </div>
</form>

urls.py:

from django.urls import path
from . import views

urlpatterns = [
    path('certificationEdit/<int:pk>', views.certificationEdit, name='certificationEdit'),
]

views.py:

@login_required(login_url='login')
def certificationEdit(request, pk):
    certification = get_object_or_404(empCertification, id=pk)
    certificationForm = empCertificationForm(instance=certification)
    if request.method == 'POST':
        certificationForm = empCertificationForm(request.POST, instance=certification)
        if certificationForm.is_valid():
            certificationForm.save()
            messages.success(request, 'Certification has been updated.')
            return redirect('certificationList')
        else:
            messages.error(request, 'Please correct form errors.')

    context = {
        'certification': certification,
        'certificationForm': certificationForm,
    }
    return render(request, 'back/pages/certification/update.html', context)

Show/Hide Form Fields:
I am using the following JavaScript function to show and hide the field while adding data.

$('select[name="certValidity"]').on('change', function(){
    if ($(this).val() == 'One Time') {
        $('.certEndDate').hide();
    } else {
        $('.certEndDate').show();
    }
});

But while retrieving the same row using Django template, it is showing all the fields.

For Example: If I saved certification validity as "One Time" which does not include "CertEndDate," and when I try to retrieve the same data, it's showing the "certEndDate" field.

So my question is how to hide the certEndDate while retrieving the "One Time" certificate data.


<details>
<summary>英文:</summary>
**models.py**:

cv_choices = (
('One Time', 'One Time'),
('Renewal', 'Renewal'),
)

class Certification(models.Model):
user = models.ForeignKey(Account, on_delete=models.CASCADE, null=True)
certName = models.CharField(('Certification Name'), max_length=100, null=True)
certId = models.CharField(
('Certification ID'), max_length=100, null=True)
certUrl = models.URLField(('Certification URL'), max_length=500, null=True)
certStartDate = models.DateField(
('Certification Start Date'), null=True)
certEndDate = models.DateField(('Certification End Date'), null=True, blank=True)
certValidity = models.CharField(
('Certification Validity'), max_length=10, choices=cv_choices, default='Renewal', null=True)
createdDate = models.DateTimeField(('Created Date'), auto_now_add=True, editable=False)
modifiedDate = models.DateTimeField(
('Modified Date'), auto_now=True, editable=False)

def __str__(self):
return self.certName

**forms.py**:

class CertificationForm(forms.ModelForm):
certValidity = forms.ChoiceField(choices=[('One Time', 'One Time'),('Renewal', 'Renewal')])

class Meta:
model = empCertification
fields = (&#39;user&#39;, &#39;certName&#39;, &#39;certId&#39;, &#39;certUrl&#39;, &#39;certStartDate&#39;, &#39;certEndDate&#39;, &#39;certValidity&#39;)
def __init__(self, *args, **kwargs):
super(empCertificationForm, self).__init__(*args, **kwargs)
self.fields[&#39;user&#39;].widget.attrs[&#39;class&#39;] = &#39;form-select&#39;
self.fields[&#39;certName&#39;].widget.attrs[&#39;class&#39;] = &#39;form-control&#39;
self.fields[&#39;certId&#39;].widget.attrs[&#39;class&#39;] = &#39;form-control&#39;
self.fields[&#39;certUrl&#39;].widget.attrs[&#39;class&#39;] = &#39;form-control&#39;
self.fields[&#39;certStartDate&#39;].widget.attrs[&#39;class&#39;] = &#39;form-control&#39;
self.fields[&#39;certEndDate&#39;].widget.attrs[&#39;class&#39;] = &#39;form-control&#39;
self.fields[&#39;certValidity&#39;].widget.attrs[&#39;class&#39;] = &#39;form-select&#39;
for field in self.fields:
self.fields[field].widget.attrs[&#39;placeholder&#39;] = &#39;Provide Details&#39;

**Edit Template File**:

<form action="{% url 'certificationEdit' certification.pk %}" method="post" class="form"
enctype="multipart/form-data" novalidate>
{% csrf_token %}
<div class="card-body border-top p-9">
{% if certificaitonForm.errors %}
{% for field in certificaitonForm %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{field.name|title}} - {{error|escape}}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in certificaitonForm.non_field_errors %}
<div class="alert alert-danger">
<strong>{{error|escape}}</strong>
</div>
{% endfor %}
{% endif %}
<div class="row">
<div class="col-lg-6">
<div class="form-floating mb-7">
{{certificaitonForm.user}}
<label class="required">User</label>
</div>
</div>
<div class="col-lg-6">
<div class="form-floating mb-7">
{{certificaitonForm.certValidity}}
<label>Certification Validity</label>
</div>
</div>
<div class="col-lg-6">
<div class="form-floating mb-7">
{{certificaitonForm.certName}}
<label class="required">Certification Name</label>
</div>
</div>
<div class="col-lg-6">
<div class="form-floating mb-7">
{{certificaitonForm.certId}}
<label class="required">Certification ID</label>
</div>
</div>
<div class="col-lg-6">
<div class="form-floating mb-7">
{{certificaitonForm.certUrl}}
<label class="required">Certification URL</label>
</div>
</div>
<div class="col-lg-6">
<div class="form-floating mb-7">
{{certificaitonForm.certStartDate}}
<label class="required">Certification Start Date</label>
</div>
</div>
<div class="col-lg-6 certEndDate">
<div class="form-floating mb-7">
{{certificaitonForm.certEndDate}}
<label>Certification End Date</label>
</div>
</div>
</div>
</div>
<div class="card-footer d-flex justify-content-end py-6 px-9">
<a href="{% url 'certificationList' %}" class="btn btn-light-info me-3">Discard</a>
<button type="submit" class="btn btn-primary">Save Changes</button>
</div>
</form>


**urls.py**

from django.urls import path
from . import views

urlpatterns = [
path('certificationEdit/<int:pk>', views.certificationEdit, name='certificationEdit'),
]


**views.py**

@login_required(login_url='login')
def certificationEdit(request, pk):
certification = get_object_or_404(empCertification, id=pk)
certificaitonForm = empCertificationForm(instance=certification)
if request.method == 'POST':
certificaitonForm = empCertificationForm(request.POST, instance=certification)
if certificaitonForm.is_valid():
certificaitonForm.save()
messages.success(request, 'Certification has been updated.')
return redirect('certificationList')
else:
messages.error(request, 'Please correct form errors.')

context = {
&#39;certification&#39;: certification,
&#39;certificaitonForm&#39;: certificaitonForm,
}
return render(request, &#39;back/pages/certification/update.html&#39;, context)

**Show/Hide Form Fields**
I am using the following JavaScript function to show and hide the field while adding data.

$('select[name="certValidity"]').on('change', function(){
if ($(this).val() == 'One Time') {
$('.certEndDate').hide();
} else {
$('.certEndDate').show();
}
});


But while retrieving the same row using Django template, it is showing all the fields. 
**For Example:** If i saved certification validity as &quot;One Time&quot; which do not include &quot;CertEndDate&quot; and when i try to retrieve the same data its showing &quot;certEndDate&quot; field. 
So my question is **how to hide the certEndDate while retrieving the &quot;One Time&quot; certificate data**.
</details>
# 答案1
**得分**: 0
我找到了上述的解决方案。
如果其他人遇到类似问题,分享这里将会有所帮助。
您需要在模板文件中添加以下内容。
```html
{% if certificaitonForm.certValidity.value != 'One Time' %}
<div class="col-lg-6 certEndDate">
<div class="form-floating mb-7">
{{certificaitonForm.certEndDate}}
<label>Certification End Date</label>
</div>
</div>
{% endif %}
英文:

I found a solution to the above.

Sharing here will help others if they have similar issues.

You need to add the following in the template file.

{% if certificaitonForm.certValidity.value != &#39;One Time&#39; %}
&lt;div class=&quot;col-lg-6 certEndDate&quot;&gt;
&lt;div class=&quot;form-floating mb-7&quot;&gt;
{{certificaitonForm.certEndDate}}
&lt;label&gt;Certification End Date&lt;/label&gt;
&lt;/div&gt;
&lt;/div&gt;
{% endif %}

huangapple
  • 本文由 发表于 2023年6月22日 04:10:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76526808.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定