4

I have the following model with a primary_key=True specified:

class Team(models.Model):
    name = models.CharField(
        max_length=64,
        primary_key=True,
    )
    ... other fields

When I serialize this model, I do the following:

class TeamSerializer(serializers.ModelSerializer):
   class Meta:
        model = Team
        fields = ('url', 'name',) # and another fields

My viewset:

class TeamViewSet(viewsets.ModelViewSet):
    lookup_value_regex = '[-\w.]'
    queryset = Team.objects.all()
    serializer_class = TeamSerializer
    filter_fields = ('name',) # and another fields

My urls.py:

router = routers.DefaultRouter()
router.register(r'teams', TeamViewSet)

urlpatterns = [
    url(r'^api/', include(router.urls)),

    # I am not sure if this url is right. I repeat of include(router.urls)
    url(r'^api/teams/(?P<name>[-\w.]+)/', include(router.urls)),

    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

Then, when I create a Team object with name attribute containing dot ., for example Latinos F.C. and I go to the rest url, I get:

enter image description here

I am not sure about of how to use the lookup_value_regex attribute in my viewset. In this answer is used with some basic regex, but if I use it, any Team object is reachable via my serialized Rest API.

How to can I get a url like as: /api/teams/Name.F.C. in my serialized Team model?

Community
  • 1
  • 1
bgarcial
  • 2,915
  • 10
  • 56
  • 123

1 Answers1

0

First of all check if you have set APPEND_SLASH to True in your settings, because if not - the missing slash (at the end of the URL) is a problem.

Second - I do not think that dot is a problem, the problem can be a space - coded as %20;

Third - such urls looks just ugly :) You should consider changing it to some kind of a slugs: Latinos F.C. -> latinos-fc;

If you do that (just add additional field on the model with slug - this field should be obviously unique) - set up the lookup_field on your view - this will solve your problem.

Consider the example:

views.py

class SomeViewSet(viewsets.ModelViewSet):
    queryset = SomeModel.objects.all()
    serializer_class = SomeSerializer
    lookup_field = 'slug_name'

serializers.py

class SomeSerializer(serializers.ModelSerializer):

    class Meta:
        model = SomeModel
        fields = ('id', 'name', 'slug_name')
        read_only_fields = ('slug_name',)

    def to_internal_value(self, data):
        ret = super(SomeSerializer, self).to_internal_value(data)
        ret['slug_name'] = slugify(ret['name'])
        return ret

models.py

class SomeModel(models.Model):
    name = models.CharField(max_length=100)
    slug_name = models.SlugField(unique=True, max_length=100)

urls.py

router.register(r'teams', SomeViewSet, base_name='teams')

urlpatterns = router.urls

And now:

creation:

enter image description here

details:

enter image description here

Can you do that this way? Or you really need the dots?

opalczynski
  • 1,599
  • 12
  • 14
  • I have `APPEND_SLASH = True` in my settings, but the inconvenient that I have is that my url does not accept the dot `.` The idea that I want is that in the name of some Team, accept the `.` like part of the string. The slug field accept dots `.` really? Should I declare the slug field as a primary_key to appear in my url? OR unique? – bgarcial Jan 11 '17 at 03:54
  • No, SlugField has only containing only letters, numbers, underscores or hyphens. But I do not understand why are you need the dots so much? I would suggest just skip the dots. You do not need to use slug field as a primary key - but you can if you want. Unique for sure, because you want to make a lookup on that field. – opalczynski Jan 11 '17 at 04:22
  • Sometimes, the name of a Team object may be Barcelona F.C. This mean that the users may type the abreviation F.C. in the name of a Team object. I want allow this case. – bgarcial Jan 11 '17 at 04:49
  • I do not know how your flow looks like - but you can always hide the slug creation step from user - when creating an object - then you will always have control of how your data looks like. The second case when user types the `Barcelona F.C.` is some kind of search I think - and this probably is not the case to discuss here. – opalczynski Jan 11 '17 at 04:54
  • Not, May be I do not explain well the case. In my model referenced above, one Team object can be created with the name `Barcelona F.C.`. Is here, in where I need the url accept dots. I hope have explained of a better way :) – bgarcial Jan 11 '17 at 05:17
  • 1
    Just edited the response - take a look. Still do not get it why you need the dots :) And why the dots are `must-have` – opalczynski Jan 11 '17 at 05:47
  • Woow your illustration is very great. I test your recommendation in a separate project, and works! :D I think that could be useful. But I have problem when I try add the `slug_name` field in my `Team` model in the migration process. I had name attribute as a `primary_key`, when I remove `primary_key`, the `id` attribute does not create in my model of automatically way. In this gif is possible watch my inconvenient https://cldup.com/mhfhg3swhe.gif My apologies, this is a newbie error. – bgarcial Jan 12 '17 at 04:42
  • Can someone please explain why dots are ugly? – igor Feb 28 '18 at 01:00