Home > database >  Django - Vue - how to generate view for tag, or?
Django - Vue - how to generate view for tag, or?

Time:04-12

Im use vue and django with rest framework. In django models.py i have model field "tahs" this is charfield with tags separated by comma. exaple : django,forest,native

I want to generate view for each tag example "django". OR try to search in filed tahs and return objects contains this tag[ex.django]

this is my views.py

class TagsResultsViewSet(viewsets.ModelViewSet):
    serializer_class = TagResultsViewSetSerializer
    queryset = CustomUserPass.objects.all()
    lookup_field = 'tahs'


    def get_queryset(self, *args, **kwargs):
        context = super().get_queryset(*args, **kwargs)
        tag = self.kwargs['tahs']
        print('this is tags:', tag)
        context =  self.queryset.filter(tahs__icontains=tag) 
        print(context)
        return context

serializer.py

class TagResultsViewSetSerializer(serializers.ModelSerializer):
    
    tahs = serializers.PrimaryKeyRelatedField(many=True, read_only=True)

    class Meta:
        model = CustomUserPass
        fields = '__all__'

urls.py

router = DefaultRouter()
...
router.register('tags', TagsPassViewSet, basename='tags')
router.register('tag', TagsResultsViewSet, basename='tag')

urlpatterns = [
    path('', include(router.urls)),
]

vue file: TagView.vue

<template>
  <div >
    <h1>You looking: {{tag}}</h1>
    <div v-for="result in results" :key="result.id">
      <div>{{result.username}}</div>
    </div>
  </div>
</template>


<script>
import axios from 'axios'
export default {
     name: 'TagView',

    data() {
        return {
            results: [],
            errors: [],
            
        }
    },

      props: {
        tag: {
        type: String,
        required: true, 
    },
    },

    mounted() {
      this.getTagsResults()
    },

        methods: {
        async getTagsResults() {

            this.$store.commit('setIsLoading', true)

            axios
                .get(`/api/v1/tag/${this.tag}`)
                .then(response => {
                     this.results = response.data
                     console.log(this.results)

                })

                
                .catch(error => {
                    console.log(error)
                })

                this.$store.commit('setIsLoading', false)


            
        },
}
}
</script>

actually when i go to http://localhost:8080/tags/linux i have output in console:

this is tags: linux
<QuerySet [<CustomUserPass: drw>, <CustomUserPass: user1>]>
Not Found: /api/v1/tag/linux/
[11/Apr/2022 11:26:44] "GET /api/v1/tag/linux/ HTTP/1.1" 404 23

edit

when i change in vue

.get(`/api/v1/tag/${this.tag}`)

to

.get('/api/v1/tag/')

and

in views

class TagsResultsViewSet(viewsets.ModelViewSet):
    serializer_class = TagResultsViewSetSerializer
    queryset = CustomUserPass.objects.all()
    lookup_field = 'tahs'
    
    
    def get_queryset(self, *args, **kwargs):
        context = super().get_queryset(*args, **kwargs)
        tag = 'django'
        print('this is tags:', tag)
        context =  self.queryset.filter(tahs__icontains=tag) 
        print(context)
        return context

it's render but tag = 'django' is hardcoded - for example.

and when i removed ${this.tag} from vue i my kwargs is empty. and i cant do just tag = self.kwargs['tahs']

urls.py (app)

router = DefaultRouter()
router.register('navbar', NavbarPassViewSet, basename='navbar')
router.register('profile', ProfilePassViewSet, basename='profile')
router.register('profiles', ProfilesPassViewSet, basename='profiles')
router.register('online', ProfilesOnlineChecker, basename='online')
router.register('projects', PassProjectAll, basename='projects')
router.register('myproject', MyProjects, basename='myproject')
router.register('project', ProjectDetail, basename='project')
router.register('tags', TagsPassViewSet, basename='tags')
router.register('tag', TagsResultsViewSet, basename='tag')

urlpatterns = [
    path('', include(router.urls)),
]

CodePudding user response:

When you go to api/v1/tags/linux/ DRF does a queryset.get(tahs="linux").

This doesn't work with your data because your tahs field might contain other words. So you get a 404 error. You could almost fix this by setting the viewset lookup_field attribute to tahs__icontains however DRF expects that it will only get one result, where as you might have multiple instances of CustomUserPass that contain "linux". That's because api/v1/tags/linux is treated as a detail endpoint for a single instance by the viewset (that returns data for a single instance), not a list endpoint (that will return data for a list of instances).

What you really want to do is add a filter using the django-filters package (which also integrates well with DRF), and then perform your API query on the list endpoint like this: api/v1/tags/?tahs=linux (or similar).

  • Related