Foreign Key field cant not be save in Django

Viewed 31

I have this two model that is related by a foreign key. I take response from a webhook regarding a transaction and save into the model. What i am trying to do is save the the foreign key element into the Transaction History but i keep getting error when data is about to be saved that Cannot assign "'1'": "TransactionHistory.level" must be a "Level" instance.

model

class Level(models.Model):
    name = models.CharField(max_length=200, null=True, blank=True,)
    fees_amount = models.PositiveSmallIntegerField()

class TransactionHistory(models.Model):
    level = models.ForeignKey(Level, on_delete=models.CASCADE, null=True, blank=True, )
    student_full_name = models.CharField(max_length=120)
    transaction_id = models.CharField(max_length=120)
    student_id_number = models.CharField(max_length=120)
    amount = models.DecimalField(default=0.0, max_digits=19, decimal_places=2)
    status = models.CharField(max_length=120, null=True, blank=True)
    email = models.EmailField(max_length=120, null=True, blank=True)
    phone = models.CharField(max_length=120, null=True, blank=True)
    date = models.DateTimeField(auto_now_add=True)


View.py 
@csrf_exempt
def webhook(request):
    # Verify if request came from Paystack
    if request.method == 'POST':
        response_data = json.loads(request.body)
        if response_data["event"] == "charge.success":
            transaction_id = (response_data["data"]["reference"])
            if not TransactionHistory.objects.filter(transaction_id=transaction_id).exists():
                status = (response_data["data"]["status"])
                amountraw = (response_data["data"]["amount"])
                student_full_name = (response_data["data"]["metadata"]["custom_fields"][0]["student_full_name"])
                level = (response_data["data"]["metadata"]["custom_fields"][0]["level"])
                student_id_number = (response_data["data"]["metadata"]["custom_fields"][0["student_id_number"])
                email = (response_data["data"]["metadata"]["custom_fields"][0]["email"])
                phone = (response_data["data"]["metadata"]["custom_fields"][0]["phone"])
                amount = (str(int(amountraw) / 100))
                if status == 'success':
                    transaction = TransactionHistory(
                        level=level,
                        student_full_name=student_full_name,
                        amount=amount,
                        transaction_id=transaction_id,
                        status=status,
                        student_id_number=student_id_number,
                        email=email,
                        phone=phone,

                    )
                    transaction.save()
    return HttpResponse(status=200)
 


This is the error i get:

 raise ValueError(
ValueError: Cannot assign "'1'": "TransactionHistory.level" must be a "Level" instance.

1 Answers

If you use the primary key, you assign this to level_id, so:

TransactionHistory(
    level_id=level,
    student_full_name=student_full_name,
    amount=amount,
    transaction_id=transaction_id,
    status=status,
    student_id_number=student_id_number,
    email=email,
    phone=phone,
)

Note: It is better to use a ModelForm [Django-doc] than to perform manual validation and saving the object. A ModelForm does not only simplify rendering a form in HTML, but it also makes it more convenient to validate the input, and store the data in the corresponding model.

Related