简体   繁体   中英

Django-rest-framework multiple url arguments

How do i map the "example object" to the url: website.com/api/<user>/<slug> .

I'm getting this
invalid literal for int() with base 10: 'username' error. so i understand that i need to use the user id in-order to map to the object, this is because I am able to map to the object if i use the user_id (integer) (url: website.com/api/<user_id>/<slug> ) instead of just the user/username (string).

Is there a way to override the default when mapping to the object from user_id (integer) to another field like user (string)?

Also i don't understand why passing the user instead of user_id in the def get_object in (Api View) does not fix this problem.

Url

urlpatterns = [
    url(r'^api/(?P<user>\w+)/(?P<slug>[\w-]+)/$', ExampleDetailAPIView.as_view(), name='example'),
]

Api View

class ExampleDetailAPIView(RetrieveAPIView):
    queryset = Example.objects.all()
    serializer_class = ExampleDetailSerializer

    def get_object(self):
        user = self.kwargs.get('user')
        slug = self.kwargs.get('slug')
        return Example.objects.get(user=user, slug=slug)

    def get_serilizer_context(self, *args, **kwargs):
        return {'request': self.request}

Serializer

class ExampleDetailSerializer(HyperlinkedModelSerializer):
    url = serializers.SerializerMethodField()

    class Meta:
        model = Example
        fields = [
            'url',
        ]

    def get_url(self, obj):
        request = self.context.get('request')
        return obj.get_api_url(request=request)

Model

class Example(models.Model):
    user                = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
    example_name         = models.CharField(max_length=100)
    slug                = models.SlugField(max_length=100, blank=True)

    class Meta:
        unique_together = ('user', 'slug')

    def get_api_url(self, request=None):
        return api_reverse('example-api:example', kwargs={'user': self.user.username, 'slug': self.slug}, request=request)

@receiver(pre_save, sender=Example)
def pre_save_example_slug_receiver(sender, instance, *args, **kwargs):
    slug = slugify(instance.example_name)
    instance.slug = slug

You can use the username in the url. For that to work you'll have to first find the user manually and then use its id to find the Example object:

def get_object(self):
    username = self.kwargs.get('username')
    slug = self.kwargs.get('slug')

    # find the user
    user = User.objects.get(username=username)

    return Example.objects.get(user=user.id, slug=slug)

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