小能豆

无法分配“'1'”:“staff.staff_type”必须是“staff_type”实例。OneToOne 字段中的 Django 错误

py

我正在开发一个小型 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”实例。


阅读 19

收藏
2024-12-11

共1个答案

小能豆

问题出在你在 add_staff_view 视图中处理 staff_type 的方式。在表单中,stafftype 的值是选定的 staff_type 的 ID(作为字符串),但在 staff.objects.create() 中,你将 staff_type 直接传递为该字符串值,而 Django 期望的是 staff_type 的实例,而不是一个 ID 字符串。

解决方案:

你需要根据 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')

解释:

  • 你从表单中获取 stafftype 的 ID(这是一个字符串),然后使用 staff_type.objects.get(id=staff_type_id) 获取对应的 staff_type 实例。
  • 将该 staff_type 实例传递给 staff 模型的 staff_type 字段。

这应该解决你遇到的错误,让你在表单提交时正确地将 staff_type 的实例存储到 staff 模型中。

2024-12-11