Django TastyPie Patch to a Many-to-Many

2019-08-25 07:00发布

问题:

I'm trying to use TastyPie Patch to a many-to-many, but I get this error:

"error_message": "Tastypie requires a Python-style path () to lazy load related resources. Only given 'SchemeResource'.",

Why?

The patch I'm making:

/participant/84
POST: {"email":"test@test.com",  "schemes":{"id":"12", "schemes"}}

Resource:

class ParticipantResource(ModelResource):

    schemes = fields.ToManyField('SchemeResource', attribute='schemes', full=True, null=True)

    class Meta:
        queryset = Participant.objects.all()
        resource_name = 'participant'
        allowed_methods = ['post', 'get', 'put', 'patch']

2nd Resource:

class SchemeResource(ModelResource):

    user = fields.ToOneField(UserResource, 'user', full=True)
    link = fields.ToOneField(SchemeLinkResource, 'link', full=True)

    class Meta:
        queryset = Scheme.objects.all()
        resource_name = 'scheme'

Model:

class Participant(models.Model):

    email = models.EmailField(unique=True)
    mobile = PhoneNumberField(null=True, blank=True)
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)

    schemes = models.ManyToManyField(Scheme)

回答1:

You must use brackets such as

[] 

around your schemes items (even if singular) when posting to a m2m field.

Request would then look like :

{"email":"test@test.com",  "schemes":[{"id":"12", "schemes"}]}

When you want to know what a request should look like, make a GET request on url/of/api/modelresource/schema/

If I recall correctly (and although you wrote "POST" in your request), PATCH request must have

{"objects": [...]}

enclosing the body.

EDIT :

Here's an example of what works for me :

Resources :

class VATCertificateResource(ModelResource):
    class Meta:
        queryset = VATCertificate.objects.all()
        resource_name = 'vatcertificate'
        authorization = Authorization()

class InterventionResource(ModelResource):

    vatcertificates = fields.ToManyField('core.api.VATCertificateResource', 'vatcertificates',
                                     related_name='intervention', null=True, blank=True, full=True)

Models :

class VATCertificate(Document):
    intervention = models.ForeignKey(Intervention, related_name='vatcertificates', blank=True, null=True)

class Intervention(models.Model):
    pass

Hope this helps,

Regards,