簡體   English   中英

無法分配“'”:“”必須是“”實例。 模型選擇字段

[英]Cannot assign "'": "" must be a "" instance. ModelChoiceField

我有一個表單,用戶可以在其中選擇對象的標題然后保存它,但是當我點擊保存時,我得到一個錯誤。 我非常確定這個問題是因為我使用的是ModelChoiceField ,它返回對象的ids而不是該對象的實例。

所以,我有兩個模型: InvoiceModel

class Invoice(models.Model):
  line_one = models.ForeignKey(Inventory, on_delete=models.CASCADE, related_name='+', verbose_name="Line 1", blank=True, null=True, default='')
  line_one_quantity = models.IntegerField('Quantity', default=0, blank=True, null=True)
  line_one_unit_price = models.IntegerField('Unit Price(₹)', default=0, blank=True, null=True)
  line_one_total_price = models.IntegerField('Line Total(₹)', default=0, blank=True, null=True)

Invoice.line_one引用到Inventory.product_number


庫存模型:

class Inventory(models.Model):
  product_number = models.IntegerField(primary_key=True)
  product = models.TextField(max_length=3000, default='', blank=True, null=True)
  title = models.CharField('Title', max_length=120, default='', blank=True, null=True, unique=True)
  amount = models.IntegerField('Unit Price', default=0, blank=True, null=True)

  def __str__(self):
    return self.title

發票形式:

class InvoiceForm(forms.ModelForm):
  line_one = forms.ModelChoiceField(queryset=Inventory.objects.values_list('title', flat=True), label="Line 1")
  line_one_unit_price = forms.CharField(widget=forms.Select, label="Unit Price(₹)")
  class Meta:
    model = Invoice
    fields = ['line_one',#...]

  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.fields['line_one_unit_price'].widget.choices = [(i.amount, i.amount) for i in Inventory.objects.all()]

我實際上有 10 行,[即line_two等],但為了簡單起見,我只是在此處粘貼 line_one 的代碼。

我還希望僅在line_one中選擇的對象數量顯示在line_one_unit_price中。 如果您知道如何實現,請告訴我。

視圖.py:

@login_required
def add_invoice(request):
  form = InvoiceForm(request.POST or None)
  total_invoices = Invoice.objects.count()
  queryset = Invoice.objects.order_by('-invoice_date')[:6]

  if form.is_valid():
    form.save()
    messages.success(request, 'Successfully Saved')
    return redirect('/invoice/list_invoice')
  context = {
    "form": form,
    "title": "New Invoice",
    "total_invoices": total_invoices,
    "queryset": queryset,
}
return render(request, "entry.html", context)

我得到的錯誤:

在此處輸入圖像描述

謝謝!

編輯:我編輯了 forms.py 並刪除了覆蓋line_one的代碼行但是現在我得到了一個完整性錯誤。

**InvoiceForm:**

class InvoiceForm(forms.ModelForm):
  line_one_unit_price = forms.CharField(widget=forms.Select, label="Unit Price(₹)")
  class Meta:
    model = Invoice
    fields = ['line_one',#...]

  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.fields['line_one_unit_price'].widget.choices = [(i.amount, i.amount) for i in Inventory.objects.all()]

錯誤:IntegrityError at /invoice/add_invoice/ NOT NULL 約束失敗:invoicecemgmt_invoice.line_three_id 請求方法:POST 請求 URL:http: //127.0.0.1 :8000/invoice/add_invoice/ Django 版本:4.0 異常類型:IntegrityError 異常值:
NOT NULL 約束失敗:invoicecemgmt_invoice.line_three_id

編輯:完整的models.py代碼:

class Invoice(models.Model):
  comments = models.TextField(max_length=3000, default='', blank=True, null=True)
  invoice_number = models.IntegerField(blank=True, null=True)
  invoice_date = models.DateField(auto_now_add=False, auto_now=False, blank=True, null=True)
  name = models.CharField('Customer Name', max_length=120, default='', blank=True, null=True)

  line_one = models.ForeignKey(Inventory, on_delete=models.CASCADE, related_name='+', verbose_name="Line 1", blank=True, default='')
  line_one_quantity = models.IntegerField('Quantity', default=0, blank=True, null=True)
  line_one_unit_price = models.IntegerField('Unit Price(₹)', default=0, blank=True, null=True)
  line_one_total_price = models.IntegerField('Line Total(₹)', default=0, blank=True, null=True)
  
  line_two = models.ForeignKey(Inventory, on_delete=models.CASCADE, related_name='+',  verbose_name="Line 2", blank=True, default='')
  line_two_quantity = models.IntegerField('Quantity', default=0, blank=True, null=True)
  line_two_unit_price = models.IntegerField('Unit Price(₹)', default=0, blank=True, null=True)
  line_two_total_price = models.IntegerField('Line Total(₹)', default=0, blank=True, null=True)
  
  line_three = models.ForeignKey(Inventory, on_delete=models.CASCADE, related_name='+',  verbose_name="Line 3", blank=True, default='')
  line_three_quantity = models.IntegerField('Quantity', default=0, blank=True, null=True)
  line_three_unit_price = models.IntegerField('Unit Price(₹)', default=0, blank=True, null=True)
  line_three_total_price = models.IntegerField('Line Total(₹)', default=0, blank=True, null=True)
  
  line_four = models.ForeignKey(Inventory, on_delete=models.CASCADE,related_name='+',  verbose_name="Line 4", blank=True, default='')
  line_four_quantity = models.IntegerField('Quantity', default=0, blank=True, null=True)
  line_four_unit_price = models.IntegerField('Unit Price(₹)', default=0, blank=True, null=True)
  line_four_total_price = models.IntegerField('Line Total(₹)', default=0, blank=True, null=True)
  
  line_five = models.ForeignKey(Inventory, on_delete=models.CASCADE, related_name='+',  verbose_name="Line 5", blank=True, default='')
  line_five_quantity = models.IntegerField('Quantity', default=0, blank=True, null=True)
  line_five_unit_price = models.IntegerField('Unit Price(₹)', default=0, blank=True, null=True)
  line_five_total_price = models.IntegerField('Line Total(₹)', default=0, blank=True, null=True)
  
  line_six = models.ForeignKey(Inventory, on_delete=models.CASCADE, related_name='+',  verbose_name="Line 6", blank=True, default='')
  line_six_quantity = models.IntegerField('Quantity', default=0, blank=True, null=True)
  line_six_unit_price = models.IntegerField('Unit Price(₹)', default=0, blank=True, null=True)
  line_six_total_price = models.IntegerField('Line Total(₹)', default=0, blank=True, null=True)
  
  line_seven = models.ForeignKey(Inventory, on_delete=models.CASCADE, related_name='+',  verbose_name="Line 7", blank=True, default='')
  line_seven_quantity = models.IntegerField('Quantity', default=0, blank=True, null=True)
  line_seven_unit_price = models.IntegerField('Unit Price(₹)', default=0, blank=True, null=True)
  line_seven_total_price = models.IntegerField('Line Total(₹)', default=0, blank=True, null=True)
  
  line_eight = models.ForeignKey(Inventory, on_delete=models.CASCADE, related_name='+',  verbose_name="Line 8", blank=True, default='')
  line_eight_quantity = models.IntegerField('Quantity', default=0, blank=True, null=True)
  line_eight_unit_price = models.IntegerField('Unit Price(₹)', default=0, blank=True, null=True)
  line_eight_total_price = models.IntegerField('Line Total(₹)', default=0, blank=True, null=True)
  
  line_nine = models.ForeignKey(Inventory, on_delete=models.CASCADE, related_name='+',  verbose_name="Line 9", blank=True, default='')
  line_nine_quantity = models.IntegerField('Quantity', default=0, blank=True, null=True)
  line_nine_unit_price = models.IntegerField('Unit Price(₹)', default=0, blank=True, null=True)
  line_nine_total_price = models.IntegerField('Line Total(₹)', default=0, blank=True, null=True)
  
  line_ten = models.ForeignKey(Inventory, on_delete=models.CASCADE, related_name='+',  verbose_name="Line 10", blank=True, default='')
  line_ten_quantity = models.IntegerField('Quantity', default=0, blank=True, null=True)
  line_ten_unit_price = models.IntegerField('Unit Price(₹)', default=0, blank=True, null=True)
  line_ten_total_price = models.IntegerField('Line Total(₹)', default=0, blank=True, null=True)
  
  phone_number = models.CharField(max_length=120, default='', blank=True, null=True)
  total = models.IntegerField(default='0', blank=True, null=True)
  balance = models.IntegerField(default='0', blank=True, null=True)
  timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
  last_updated = models.DateTimeField(auto_now_add=False, auto_now=True, blank=True)
  paid = models.BooleanField(default=False)
  invoice_type_choice = (
  ('Invoice', 'Invoice'),
  ('Receipt', 'Receipt'),
  )
  invoice_type = models.CharField(max_length=50, blank=True, null=True, choices=invoice_type_choice)
def __unicode__(self):
    return self.invoice_number

forms.py

class InvoiceForm(forms.ModelForm):
                       
  line_one_unit_price = forms.CharField(widget=forms.Select, label="Unit Price(₹)")
  line_two_unit_price = forms.CharField(widget=forms.Select, label="Unit Price(₹)")
  line_three_unit_price = forms.CharField(widget=forms.Select, label="Unit Price(₹)")
  line_four_unit_price = forms.CharField(widget=forms.Select, label="Unit Price(₹)")
  line_five_unit_price = forms.CharField(widget=forms.Select, label="Unit Price(₹)")
  line_six_unit_price = forms.CharField(widget=forms.Select, label="Unit Price(₹)")
  line_seven_unit_price = forms.CharField(widget=forms.Select, label="Unit Price(₹)")
  line_eight_unit_price = forms.CharField(widget=forms.Select, label="Unit Price(₹)")
  line_nine_unit_price = forms.CharField(widget=forms.Select, label="Unit Price(₹)")
  line_ten_unit_price = forms.CharField(widget=forms.Select, label="Unit Price(₹)")

  class Meta:
      model = Invoice
      fields = ['name', 'phone_number', 'invoice_date', 'invoice_number',
            'line_one', 'line_one_quantity', 'line_one_unit_price', 'line_one_total_price',
            'line_two', 'line_two_quantity', 'line_two_unit_price', 'line_two_total_price',
            'line_three', 'line_three_quantity', 'line_three_unit_price', 'line_three_total_price',
            'line_four', 'line_four_quantity', 'line_four_unit_price', 'line_four_total_price',
            'line_five', 'line_five_quantity', 'line_five_unit_price', 'line_five_total_price',
                            'line_six', 'line_six_quantity', 'line_six_unit_price', 'line_six_total_price',
            'line_seven', 'line_seven_quantity', 'line_seven_unit_price', 'line_seven_total_price',
            'line_eight', 'line_eight_quantity', 'line_eight_unit_price', 'line_eight_total_price',
            'line_nine', 'line_nine_quantity', 'line_nine_unit_price', 'line_nine_total_price',
            'line_ten', 'line_ten_quantity', 'line_ten_unit_price', 'line_ten_total_price',
            'total', 'paid', 'invoice_type'
            ]

      widgets = {
          'line_one_quantity': TextInput(),
          'line_two_quantity': TextInput(),
          'line_three_quantity': TextInput(),
          'line_four_quantity': TextInput(),
          'line_five_quantity': TextInput(),
          'line_six_quantity': TextInput(),
          'line_seven_quantity': TextInput(),
          'line_eight_quantity': TextInput(),
          'line_nine_quantity': TextInput(),
          'line_ten_quantity': TextInput(),
    }

def clean_invoice_number(self):
    invoice_number = self.cleaned_data.get('invoice_number')
    if not invoice_number:
        raise forms.ValidationError('This field is required')
    return invoice_number


def clean_name(self):
    name = self.cleaned_data.get('name')
    if not name:
        raise forms.ValidationError('This field is required')
    return name

def clean_line_one(self):
    line_one = self.cleaned_data.get('line_one')
    if not line_one:
        raise forms.ValidationError('This field is required')
    return line_one

def clean_line_one_quantity(self):
    line_one_quantity = self.cleaned_data.get('line_one_quantity')
    if not line_one_quantity:
        raise forms.ValidationError('This field is required')
    return line_one_quantity

def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.fields['line_one_unit_price'].widget.choices = [(i.amount, i.amount) for i in Inventory.objects.all()]
    self.fields['line_two_unit_price'].widget.choices= [(i.amount, i.amount) for i in Inventory.objects.all()]
    self.fields['line_three_unit_price'].widget.choices = [(i.amount, i.amount) for i in Inventory.objects.all()]
    self.fields['line_four_unit_price'].widget.choices = [(i.amount, i.amount) for i in Inventory.objects.all()]
    self.fields['line_five_unit_price'].widget.choices = [(i.amount, i.amount) for i in Inventory.objects.all()]
    self.fields['line_six_unit_price'].widget.choices = [(i.amount, i.amount) for i in Inventory.objects.all()]
    self.fields['line_seven_unit_price'].widget.choices = [(i.amount, i.amount) for i in Inventory.objects.all()]
    self.fields['line_eight_unit_price'].widget.choices = [(i.amount, i.amount) for i in Inventory.objects.all()]
    self.fields['line_nine_unit_price'].widget.choices = [(i.amount, i.amount) for i in Inventory.objects.all()]
    self.fields['line_ten_unit_price'].widget.choices = [(i.amount, i.amount) for i in Inventory.objects.all()]

在 ModelChoiceField 內的 queryset 屬性中,您應該發送 pk 以及要顯示的屬性。 例如:

forms.ModelChoiceField(queryset=Inventory.objects.values('pk','title'), label="Line 1")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM