Как получить текущий идентификатор пользователя, чтобы связать его с внешним ключом модели моего продукта в Django Rest-framework & Vue. js - PullRequest
0 голосов
/ 29 апреля 2020

Я пытаюсь получить свой идентификатор пользователя после входа в систему. Токен уже сохранен в localstorage

, работающем на Django в качестве внутреннего интерфейса и Vue. js в качестве внешнего интерфейса

так что пользователь может входить и выходить из системы, но я не могу найти userId вошедшего в систему пользователя, который может получить больше данных, связанных с пользователем.

Поэтому я не могу опубликовать продукт правильно относится к пользователю. кроме того, если мне удастся опубликовать и проверить через консоль на chrome, он говорит, что раздел моей категории пуст / пуст

Всякий раз, когда я пытаюсь связать свое внешнее поле категории в модели продукта, я получаю эту ошибку ниже

{category: ["Invalid hyperlink - No URL match."]}
category: ["Invalid hyperlink - No URL match."]
0: "Invalid hyperlink - No URL match.

Заранее спасибо

my model.py

from django.db import models
from django.contrib.auth.models import User
# class User(models.Model):
#     id_user = models.DecimalField(max_digits=10, decimal_places=2, null=True)
#     def __str__(self):
#        return self.id_user

class Category(models.Model):
    name = models.CharField(max_length = 200, null = True,)

    def __str__(self):
       return self.name

class State(models.Model):

    STATE_CHOICES = [('Ordered', 'Ordered'), ('Pending', 'Pending'),
        ('Placed', 'Placed'), ('Reserved', 'Reserved')
    ]
    state = models.CharField(max_length = 200, null = True,
    choices = STATE_CHOICES)

    def __str__(self):
       return self.state

class Product(models.Model):
    user = models.ForeignKey(User,null=True, on_delete=models.SET_NULL)
    state = models.ForeignKey(State, null=True, on_delete=models.SET_NULL)
    category = models.ForeignKey(Category, null=True, on_delete=models.SET_NULL)
    title = models.CharField(max_length=200)
    description = models.TextField(max_length=800, null=True)
    price = models.DecimalField(max_digits=10, decimal_places=2, null=True)
    #image = models.ImageField(upload_to='post_image', blank=True, width_field=None, height_field=None, max_length=100,)
    date_created = models.DateTimeField(auto_now_add=True, null=True)

    class Meta:
        unique_together = (('user','title'),)
        index_together = (('user','title'),) 


    # CATEGORY_CHOICES = (
    #     ('Books', 'Books'),
    #     ('eBooks','eBooks'),
    #     ('Writing material','Writing material'),
    # )
    # category = models.CharField(max_length=200, null=True, choices=CATEGORY_CHOICES)



    SCHOOL_CHOICES = (
        ('Erasmushogeschool | EHB',(
            ('Campus Kaai', 'Campus Kaai'),
            ('Campus Bloemberg', 'Campus Bloemberg'),
        )),
        ('Vrije Universiteit Brussel | VUB',(
            ('Campus Jette', 'Campus Jette'),
            ('Campus Schaarbeek', 'Campus Schaarbeek'),
        )),
        ('Katholieke universiteit leuven | KUL',(
            ('KUL Gent', 'KUL Gent'),
            ('Campus Antwerpen', 'Campus Antwerpen'),
        )),
    )
    school = models.CharField(max_length=50, choices=SCHOOL_CHOICES, null=True)

    MAJOR_CHOICES = (
        ('IT','IT'),
        ('Marketing','Marketing'),
        ('DIFF','DIFF'),
    )
    major = models.CharField(max_length=200,choices=MAJOR_CHOICES, null=True)

    SUBJECT_CHOICES = [
        ('Mathematics','Mathematics'),
        ('Algoritmes','Algoritmes'),
        ('Analyses','Analyses'),
    ]
    subject = models.CharField(max_length=200,choices=SUBJECT_CHOICES, null=True)

    CONDITION_CHOICES = [
        ('New','New'),
        ('Used','Used'),
    ]
    condition = models.CharField(max_length=200,choices=CONDITION_CHOICES, null=True)

    LOCATION_CHOICES = [
        ('Brussel','Brussel'),
        ('Leuven','Leuven'),
        ('Gent','Gent'),
        ('Antwerpen','Antwerpen'),
    ]
    location = models.CharField(max_length=200,choices=LOCATION_CHOICES, null=True)


    def __str__(self):
        return self.title

serializer.py

from rest_framework import serializers
from .models import Product, State, Category
from django.contrib.auth.models import User
from rest_framework.authtoken.models import Token

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'username', 'password')
        extra_kwargs = {'password':{'write_only':True,'required':True}}

    def create(self, validated_data):
      user = User.objects.create_user(**validated_data)
      print(user)
      Token.objects.create(user=user)
      return user


class ProductSerializer(serializers.HyperlinkedModelSerializer):
    category_name = serializers.CharField(source='category.name', read_only=True)

    class Meta:
        model = Product
        fields = '__all__'


class CategorySerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Category
        fields = ('id', 'url', 'name')

class StateSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = State
        fields = '__all__'

urls.py

from django.contrib.auth.models import User
from rest_framework import routers, serializers, viewsets
from django.urls import path
from restapi.views import ProductViewSet, StateViewSet, UserViewSet, CategoryViewSet

# class UserSerializer(serializers.HyperlinkedModelSerializer):
#     class Meta:
#         model = User
#         fields = ['id', 'url', 'username', 'email', 'is_staff']

# # ViewSets define the view behavior.
# class UserViewSet(viewsets.ModelViewSet):
#     queryset = User.objects.all()
#     serializer_class = UserSerializer

# Routers provide an easy way of automatically determining the URL conf.
router = routers.DefaultRouter()
router.register('users', UserViewSet)
router.register('product', ProductViewSet)
router.register('category', CategoryViewSet)
router.register('state', StateViewSet)

urlpatterns = [
    path('', include(router.urls)),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
 ]

views.py

from django.shortcuts import render
from  rest_framework import viewsets, status
from .models import Product, State, Category
from django.contrib.auth.models import User
from .serializer import ProductSerializer, UserSerializer, StateSerializer, CategorySerializer
from rest_framework.permissions import IsAuthenticated,AllowAny
from rest_framework.authentication import TokenAuthentication
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import SearchFilter, OrderingFilter
from rest_framework.response import Response
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    authentication_classes = (TokenAuthentication,)
    permission_calsses = (IsAuthenticated,)
    filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
    search_fields = ('title', 'price', 'category__name')

    # def delete(self,request,*args,**kwargs):
    #     response = {'message':'product cannot be updated like this'}
    #     return Response(response, status = statu.HTTP_400_BAD_REQUEST)

    # def create(self,request,*args,**kwargs):
    #     response = {'message':'product cannot be created like this'}
    #     return Response(response, status = status.HTTP_400_BAD_REQUEST)

class CategoryViewSet(viewsets.ModelViewSet):
    queryset = Category.objects.all()
    serializer_class = CategorySerializer
    permission_calsses = (IsAuthenticated,)
    filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
    search_fields = ('name', 'id')

class StateViewSet(viewsets.ModelViewSet):
    queryset = State.objects.all()
    serializer_class = StateSerializer
    permission_calsses = (IsAuthenticated,)

class UserViewSet(viewsets.ModelViewSet):
  queryset = User.objects.all()
  serializer_class = UserSerializer
  authentication_classes = (TokenAuthentication,)
  permission_classes = (AllowAny, )

# class CustomObtainAuthToken(ObtainAuthToken):
#     def post(self, request, args, *kwargs):
#         response = super(CustomObtainAuthToken, self).post(request, args, *kwargs)
#         token = Token.objects.get(key=response.data['token'])
#         return Response({'token': token.key, 'id': token.user_id})

мой интерфейс Vue. js логин

<template>
 <div class="login-form">
          <b-form @submit.prevent="login" v-if="token==null">
            <div class="sign-in-htm">
              <div class="group">
                <label for="user" class="label">Username</label>
                <input id="user" type="text" class="input" required v-model="username">
              </div>
              <div class="group">
                <label for="pass" class="label">Password</label>
                <input
                  id="pass"
                  type="password"
                  class="input"
                  data-type="password"
                  v-model="password"
                  required>
              </div>

some more code...
</template>


<script>

export default {
  name: "login",
  data() {
    return {
      username: '',
      user_id : 0,
            password: '',
            repeat: '',
      submitted: false,
      token: null,
      log_status: ''
    }
  }, 
  methods: {
    login() {
      axios
        .post("http://127.0.0.1:8000/auth/", {
          username: this.username,
          password: this.password
        })
        .then(res => {
          this.token = res.data.token;
          this.log_status = "Log out";
          this.$root.$emit("logAndToken", this.log_status, this.token);
          console.log(
            "Login data:",
            res,
            this.username,
            this.password,
            this.token
          );
          localStorage.setItem("logAndToken", this.token);
          localStorage.setItem("user_id", this.user_id);
        });
        this.$router.push({ name: "homepage" }).catch(err => {
        localStorage.removeItem("logAndToken");
        localStorage.removeItem("user_id");
        console.log("error loginn", err);

      });
    },
    register() {
      console.log(this.username);
      axios
        .post("http://127.0.0.1:8000/auth/", {
          username: this.username,
          password: this.password
        })
        .then(res => console.log(res))
                .catch(err => console.log(err));
this.submitted = true;
        this.$validate()
          .then(function(success) {
            if (success) {
              alert('Validation succeeded!');
            }
          });
      this.$router.push({ name: "useradmin" });
        },
       submit: function () {
        this.submitted = true;
        this.$validate()
          .then(function(success) {
            if (success) {
              alert('Validation succeeded!');
            }
          });
      }

</script>

мой navbar вверху | в этом компоненте я проверяю, есть ли у меня токен или нет с помощью v-for

<template>

 <li class="nav-item dash">
                 <a  class="nav-link pr-2 h5 font-weight-bold" type="button" @click.prevent="$router.push({ name: 'useradmin' }).catch(err => {})" v-if="this.token!=null">Dasboard</a>
            </li>
          <li class="nav-item">
                 <a  class="nav-link pr-2 h5" type="button" @click.prevent="$router.push({ name: 'sdf' }).catch(err => {})" v-if="this.token!=null" v-on:click="logout()" >{{this.log_status}}</a>
            </li> 
            <li class="nav-item">
                 <a class="nav-link pr-2 h5" type="button" @click.prevent="$router.push({ name: 'sdf' }).catch(err => {})" v-if="this.token==null">{{this.log_status}}</a>
            </li>

// more code

</template>

<script>

var url_category = 'http://127.0.0.1:8000/category/'

export default {
  name: "Menu",
  components: {},
  props: [],
  data() { 
    return {
      categories:[],
      title: '',
      token: null,
      log_status: this.token?'log out':'log in',
    };

  }, 
  mounted() {
    this.$root.$on('logAndToken', (log_status, token)  => {
      this.token = token
      this.log_status = log_status
      console.log('message received from login + token' ,log_status, token);
    })
  },
  methods: {
   sendCategoryName(category_name){
   this.$root.$emit('message', category_name)

   },
  logout(){
                    localStorage.removeItem('logAndToken');
                    this.token = null;
                    this.log_status = "Log in"
                    this.$root.$emit('logAndToken', this.log_status, this.token)
            }
  },
    created() {
    axios.get(url_category).then(res => (this.categories = res.data))
    .catch(err => console.log("error", err));


    /*   To check if anything is coming trough, i console log the result:
           .then(res => console.log(res))
           My records were in the array 'results'
          */

    // get the Records form the API use Vue detected tool extention via chrome.
  }
};


 </script>

Ответы [ 2 ]

0 голосов
/ 02 мая 2020

Если вы хотите хранить дополнительную информацию, рекомендуется использовать токены JWT. Когда вы отправляете токен с сервера, вы можете закодировать дополнительную информацию в полезную нагрузку ответа.

Например, ваша полезная нагрузка может выглядеть так, когда она закодирована.

{
   token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
}

Когда вы декодируете ее из приложения внешнего интерфейса

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

Взгляните на https://jwt.io/

В настоящий момент кажется, что вы не закодировали какую-либо другую дополнительную информацию в своем ответе.

0 голосов
/ 02 мая 2020

Вы можете получить user_id из объекта запроса. request.user.id

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...