简体   繁体   中英

Editing the foreign key field in Serializer - Django Rest Framework

I am using Django Rest Framework. I am using this suggestion for adding new value in auto-suggest Select2 dropdown but allow new values by user? . But it seems almost impossible for me.

Payee is the foreign key field. If string along with '(NEW)' is returned instead of primary key, I need to create the object in the Contacts model and should set primary key of the newly created object to payee field.

models.py

class Contacts(models.Model):
    no = models.AutoField(primary_key=True)
    name = models.CharField(max_length=25)
class Transactions(models.Model):
    payee = models.ForeignKey(Contacts,null=True, related_name = 'transactions_payee')
    reminder = models.ForeignKey(Reminders, related_name='transaction_reminders',blank=True, null=True) 

serializers.py

class TransactionSerializer(serializers.ModelSerializer):
    reminder = ReminderSerializer()

    class Meta:
      model = Transactions
      fields=('pk','payee','reminder'...)

    def validate_payee(self, value):
      if "  (NEW)" not in value:
        return value
      else:
        payee = value.replace("  (NEW)", "")
        contact = Contacts.objects.create(name = payee)
        value = contact.no
        return value

    def create(self, validated_data):
       ...  #writable nested serializer for reminder field.

    def update(self, instance, validated_data):
       ...  #writable nested serializer for reminder field.

The validate_payee is not even called. I even tried adding the same logic inside create() but somewhere the django's default validator comes before all of that and throws the error message saying

{payee: ["Incorrect type. Expected pk value, received unicode."]}

I am a beginner in Django. I have search almost all the stackoverflow questions. Nothing works for me or maybe I am making a mistake somewhere.

Solution #1

{payee: ["Incorrect type. Expected pk value, received unicode."]}

Above error happens because TransactionSerializer is handling field "payee" as ForeignKeyField (like a PK).

So when your validate_payee method is called instead of return a PK value, you are returning a unicode string.

I think that you are trying to handle payee in valdiate_payee as an instance of Payee model.

If that is what you want, then my suggestion will be to update TransactionSerializer and try adding one of this lines:

reminder = ReminderSerializer()
payee = PayeeSerializer() # This is one
payee = ContactSerializer() # Or this one.

Doing the above make sure your validate_payee function returns an instance of Contact.

If validation is not ok, just raise ValidationError ( http://www.django-rest-framework.org/api-guide/exceptions/#validationerror )

Solution #2 Try to change: value = contact.no by value = contact.id

Recomendation, if you are just starting with DRF, to inspect your code, just insert: import ipdb; ipdb.set_trace() import ipdb; ipdb.set_trace() this will set a break-point with interactive python shell so you can check if that code is being executed and also you can check the current content of your variables.

In your case if you want to check if validate_payee is being executed, try:

def validate_payee(self, value):
      import ipdb; ipdb.set_trace()
      if "  (NEW)" not in value:
        return value
      else:
        payee = value.replace("  (NEW)", "")
        contact = Contacts.objects.create(name = payee)
        value = contact.no
        return value

Hope this can help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM