我正在开发一个小型 django-python 项目,它有两个模型“staff_type”和“staff”。在staff_type模型中,只填充了职位和日期字段。而在 staff模型中,存在 staff_type 的 OneToOneField 关系。这意味着每当用户想要添加员工时,他/她必须先添加 staff_type,然后在 staff 模块中,用户将从选择菜单中选择员工类型(职位),其中分别显示所有 staff_type。
现在,每当用户选择任何职位(staff_type)并填写整个表格时,我都希望将选定的staff_type id 存储在员工模型/表中。
注意:我已经从 django admin 尝试过这个,并且它运行完美,但我想在自己设计的模板中做同样的工作。
Modles.py
class staff_type(models.Model): designation = models.CharField(max_length=50) salary = models.IntegerField() datetime = models.DateTimeField() entrydatetime = models.DateTimeField( auto_now=False, auto_now_add=False) class staff(models.Model): staff_type = models.OneToOneField(staff_type, on_delete=models.CASCADE) firstname = models.CharField(max_length=50) lastname = models.CharField(max_length=50) fathername = models.CharField(max_length=50) city = models.CharField(max_length=50) country = models.CharField(max_length=50) state = models.CharField(max_length=50) zip = models.IntegerField(blank=True) address = models.CharField(max_length=100) contact =models.CharField(max_length=20) cnic = models.CharField(max_length=14) photo = models.ImageField() cv = models.ImageField() otherfiles = models.ImageField()
views.py
def add_staff_type(request): if request.method == 'POST': designation = request.POST.get('designation') salary = request.POST.get('salary') datetime = request.POST.get('datetime') add_staff_type = staff_type.objects.create(designation=designation, salary=salary, datetime=datetime, entrydatetime = dt.now()) add_staff_type.save() messages.info(request, "Staff type has been Added.") return redirect('add_staff_type') else: #fetching records from the database table display_staff_type = staff_type.objects.all() return render(request, 'staff/staff_type.html',{'display_staff_type':display_staff_type}) #this view is for fetching the designation column and displaying in the select tag #and rendering add_staff html form def add_staff(request): staff = staff_type.objects.all() return render(request, 'staff/add_staff.html', {'staff':staff}) #this view is for adding the staff def add_staff_view(request): if request.method == 'POST': staff_type = request.POST.get('stafftype') firstname = request.POST.get('firstname') lastname = request.POST.get('lastname') fathername = request.POST.get('fathername') city = request.POST.get('city') country = request.POST.get('country') state = request.POST.get('state') zipcode = request.POST.get('zip') contact = request.POST.get('contact') cnic = request.POST.get('cnic') address = request.POST.get('address') photo = request.FILES.get('photo') cv = request.FILES.get('cv') otherfiles = request.FILES.get('photo') add_staff = staff.objects.create(firstname=firstname, lastname=lastname, fathername=fathername, city=city,country=country, state=state, contact=contact, cnic=cnic, zip=zipcode, address=address, photo=photo, cv=cv, otherfiles=otherfiles, staff_type=staff_type) add_staff.save() messages.info(request, "Staff has been Added.") return redirect('add_staff') else: return render(request, 'staff/add_staff.html')
urls.py
urlpatterns = [ path("", views.index, name="index"), path("staff/add_staff_type", views.add_staff_type, name="add_staff_type"), path("staff/add_staff", views.add_staff, name="add_staff"), path("staff/add_staff_view", views.add_staff_view, name="add_staff_view"), ]
add_staff.html
<form class="needs-validation" action="add_staff_view" method="POST" enctype="multipart/form-data" novalidate> {% csrf_token %} <div class="card-body"> <div class="form-row"> <div class="col-md-3 mb-3"> <label for="validationCustom01">Staff Type</label> <select class="form-control" id="validationCustom01" name="stafftype"> {% for staff in staff %} <option name="stafftype" value="{{ staff.id }}" required>{{staff.designation}}</option> {% endfor %} </select> <div class="valid-feedback"> Looks good! </div> </div> <div class="col-md-3 mb-3"> <label for="validationCustom02">First name</label> <input type="text" class="form-control" id="validationCustom02" placeholder="First name" name="firstname" required> <div class="valid-feedback"> Looks good! </div> </div> <div class="col-md-3 mb-3"> <label for="validationCustom03">Last name</label> <input type="text" class="form-control" id="validationCustom03" placeholder="Last name" name="lastname" required> <div class="valid-feedback"> Looks good! </div> </div> <div class="col-md-3 mb-3"> <label for="validationCustom04">Father Name</label> <input type="text" class="form-control" id="validationCustom04" placeholder="Father Name" name="fathername" required> <div class="valid-feedback"> Looks good! </div> </div> </div> <div class="form-row"> <div class="col-md-3 mb-3"> <label for="validationCustom05">City</label> <input type="text" class="form-control" id="validationCustom05" placeholder="City" name="city" required> <div class="invalid-feedback"> Please provide a valid city. </div> </div> <div class="col-md-3 mb-3"> <label for="validationCustom06">Country</label> <input type="text" class="form-control" id="validationCustom06" value="Pakistan" name="country" required> <div class="invalid-feedback"> Please provide a valid country. </div> </div> <div class="col-md-3 mb-3"> <label for="validationCustom07">State</label> <input type="text" class="form-control" id="validationCustom07" placeholder="State" name="state" > </div> <div class="col-md-3 mb-3"> <label for="validationCustom08">Zip</label> <input type="number" class="form-control" id="validationCustom08" value="0000" name="zip"> </div> </div> <div class="form-row"> <div class="col-md-3 mb-3"> <label for="validationCustom09">Contact</label> <input type="text" class="form-control" id="validationCustom09" placeholder="Phone Number" name="contact" required> <div class="invalid-feedback"> Please provide a valid country. </div> </div> <div class="col-md-3 mb-3"> <label for="validationCustom10">CNIC</label> <input type="number" class="form-control" id="validationCustom10" placeholder="xxxxx-xxxxxxx-x" name="cnic" required> <div class="invalid-feedback"> Please provide a valid country. </div> </div> <div class="col-md-6 mb-3"> <label for="address">Address</label> <input type="text" class="form-control" id="address" placeholder="Current Address" name="address"> </div> </div> <div class="form-row"> <div class="file col-md-4 mb-3"> <label class="file-label" for="customFile01">Photo</label> <input type="file" class="form-control" id="customFile01" name="photo"/> </div> <div class="file col-md-4 mb-3"> <label class="file-label" for="customFile02">CV</label> <input type="file" class="form-control" id="customFile02" name="cv"/> </div> <div class="file col-md-4 mb-3"> <label class="file-label" for="customFile03">Other Files/Photos</label> <input type="file" class="form-control" id="customFile03" name="otherfiles"/> </div> </div> <div classs="form-row"> <button class="btn btn-primary" type="submit">Add Staff</button> </div> </div> </div> </form>
我尽力编写了上述代码,但它给出了错误。
错误
异常值: 无法分配“‘1’”:“staff.staff_type”必须是“staff_type”实例。
问题出在你在 add_staff_view 视图中处理 staff_type 的方式。在表单中,stafftype 的值是选定的 staff_type 的 ID(作为字符串),但在 staff.objects.create() 中,你将 staff_type 直接传递为该字符串值,而 Django 期望的是 staff_type 的实例,而不是一个 ID 字符串。
add_staff_view
staff_type
stafftype
staff.objects.create()
你需要根据 ID 获取对应的 staff_type 实例,然后将其赋值给 staff_type 字段。修改你在 add_staff_view 视图中的 staff_type 赋值部分:
def add_staff_view(request): if request.method == 'POST': staff_type_id = request.POST.get('stafftype') # 获取stafftype的ID staff_type_instance = staff_type.objects.get(id=staff_type_id) # 根据ID获取staff_type实例 firstname = request.POST.get('firstname') lastname = request.POST.get('lastname') fathername = request.POST.get('fathername') city = request.POST.get('city') country = request.POST.get('country') state = request.POST.get('state') zipcode = request.POST.get('zip') contact = request.POST.get('contact') cnic = request.POST.get('cnic') address = request.POST.get('address') photo = request.FILES.get('photo') cv = request.FILES.get('cv') otherfiles = request.FILES.get('photo') # 将staff_type实例传递给staff模型 add_staff = staff.objects.create( firstname=firstname, lastname=lastname, fathername=fathername, city=city, country=country, state=state, contact=contact, cnic=cnic, zip=zipcode, address=address, photo=photo, cv=cv, otherfiles=otherfiles, staff_type=staff_type_instance ) add_staff.save() messages.info(request, "Staff has been Added.") return redirect('add_staff') else: return render(request, 'staff/add_staff.html')
staff_type.objects.get(id=staff_type_id)
staff
这应该解决你遇到的错误,让你在表单提交时正确地将 staff_type 的实例存储到 staff 模型中。