Search code examples
pythondjangotastypie

One-One object not being linked to Existing Object


Not being able to post a one one related object with resource uri :

 http://127.0.0.1:8000/api/v1/job/ 
{ "name":"jobstestfinal2",
  "payment":"/api/v1/payment/2/"
}

getting no error . just null in place of payment object.

models.py

class Job(models.Model):
    name = models.CharField(max_length=200)


class Payment(models.Model):
    scheduled = models.DateTimeField()
    job = models.OneToOneField(
        Job,
        related_name="payment",
        blank=True,
        null=True)

resource.py

  class PaymentResource(ModelResource):
        job = fields.ToOneField(
            'myapp.resources.JobResource',
            'job', null=True, blank=True)

        class Meta:
            queryset = Payment.objects.all()
            resource_name = 'payment'
            authorization = Authorization()
            allowed_methods = ('get', 'put', 'post')


class JobResource(ModelResource):
    payment = fields.ToOneField(
        PaymentResource,
        'payment',
        related_name='job',
        null=True, blank=True
    )

    class Meta:
        queryset = Job.objects.all()
        resource_name = 'job'
        authorization = Authorization()
        allowed_methods = ('get', 'put', 'post')

FYI following end points are working fine :
GET job , payment
POST job [ with payment object ]
payment [ with job uri ]
payment [ with job object ]


Solution

  • If you want to use the example post url that you posted.

    http://127.0.0.1:8000/api/v1/job/ 
    
    { "name":"jobstestfinal2",
      "payment":"/api/v1/payment/2/" # Not sure if you have to use payment_set or not.
    }
    

    change your foreign key from Payment to Job

    class Job(models.Model):
      name = models.CharField(max_length=200)
      payment = models.ForeignKey( # Changed from OneToOne to ForeingKey
        Payment,
        blank=True, # True means a job doesn't have to have a payment
        null=True # Allowing the value NULL in your database
      )
    
    class Payment(models.Model):
      scheduled = models.DateTimeField()
    

    You can add Payment to a Job

    job = Job(name='nice job')
    job.save() # Your Job must have an ID before you can link it to a Payment
    payment = Payment(scheduled='2014-1-1 10:00')
    job.payment_set.add(payment)
    job.save()
    

    and a Job to a Payment.

    job = Job(name='nice job')
    job.save() # Your Job must have an ID before you can link it to a Payment
    payment = Payment(scheduled='2014-1-1 10:00')
    payment.job = job # The difference is the _set.add when you do it through the Job model
    payment.save()