Django.fun

Vue Js and Django get fields from ForeignKey Objects

I am using Django Rest Framework with Vue JS and currently unable to get the foreignkey fields from the actual model of the api. I want to be able to get the store name of a particular product. Whenever I try to call [[ product.store.name ]] in my vue template it returns nothing. Also my href does not return the slug of a store. This could be an easy fix, but I am hopeful to get a solution. Below is my code, thanks.

models.py
class Store(models.Model):
    owner = models.ForeignKey("account.Profile", null=True, on_delete=models.SET_NULL)
    category = models.ForeignKey("store.Category", null=True, on_delete=models.SET_NULL)
    name = models.CharField(max_length=30, unique=True)
    slug = AutoSlugField(populate_from='name', unique=True, editable=True)
    description = models.CharField(max_length=255, blank=True)

    def __str__(self):
        return str(self.id)


class Product(models.Model):
    store = models.ForeignKey("store.Store", null=True, on_delete=models.SET_NULL, related_name='product_store')
    category = models.ForeignKey("store.Category", related_name='product_category', on_delete=models.CASCADE)
    sub_category = models.ForeignKey("store.SubCategory", related_name='product_sub_category', on_delete=models.SET_NULL, blank=True, null=True)
    created_by = models.ForeignKey(Profile, on_delete=models.CASCADE, related_name='product_creator')
    title = models.CharField(max_length=255)
    description = models.TextField(blank=True)
    slug = AutoSlugField(populate_from='title', unique=True)
    price = models.DecimalField(max_digits=10, decimal_places=0)


serializer.py
class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = '__all__'


views.py
class ProductListAPIView(generics.ListAPIView):
    pagination_class = MyCustomPagination
    queryset = Product.objects.all().order_by('-date_created')
    # queryset = Product.objects.all()
    serializer_class = ProductSerializer



products.js
<script>
  new Vue({
    el: "#blog",
      delimiters: ['[[', ']]'],
      data() {
          return {
              products: [],
              currentPage: 1,
              hasNext: true,
              loading: true,
              errored: false,
          }
      },
      mounted() {
          this.getProducts()

          window.onscroll = () => {
              let bottomOfWindow = document.documentElement.scrollTop + window.innerHeight === document.documentElement.offsetHeight

              if (bottomOfWindow && this.hasNext) {
                  this.currentPage += 1
                  this.getProducts()
              }
          }
      },
      methods: {
          getProducts() {
              console.log('Get products')

              fetch(`http://127.0.0.1:8000/store/apis/views/product-list-api-view/?page=${this.currentPage}`)
                  .then(response => {
                      return response.json()
                  })
                  .then(data => {
                      console.log(data)

                      this.hasNext = false

                      if (data.next) {
                          this.hasNext = true
                      }

                      for (let i = 0; i < data.results.length; i++) {
                          this.products.push(data.results[i])
                      }
                  })
                  .catch(error => {
                      console.log(error)
                      this.errored = true;
                  })
                  .finally(() => (
                      this.loading = false,
                      document.getElementById("loading-done-products").classList.remove('d-none')
                      // document.getElementById("error-while-loading").classList.remove("d-none")
                  ));
          },


          formatPrice(value) {
              let val = (value / 1).toFixed(0).replace('.', '.')
              return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")
          }

      }
  // }

  })
</script>





products.html
<div id="blog" class="container-fluid">

            <div id="app-the-main" class="">
                <h4 class="text-center sub-cat-title pb-4">All Products</h4>
                <section v-if="errored">
                  <p class="text-center">We're sorry, we're not able to retrieve this information at the moment, please try back later
                  </p>
                </section>
              
              
                <section v-else>
                  <div class="row row-cols-2 row-cols-sm-2 row-cols-md-4 g-3">
                    <div v-if="loading" class="spinner-border text-primary my-5" style="margin: auto;" role="status">
                      <span class="sr-only">Loading...</span>
                    </div>
                   
                    <div v-else v-for="product in products" class="col">
                      <a class="text-dark text-decoration-none" v-bind:href="[[ product.store.slug ]]+'products/'+[[ product.slug ]]">
                        <div class="card border-0">
                          <img class="img-fluid" alt="Responsive image" :src="product.main_image_small_thumbnail"
                            style="width: 200px; height: 150px;">
                          <div class="card-body px-0">
                            <p class="card-text px-2" style="font-weight: 400; font-size: 14px;">
                              [[ product.title.substring(0,18)+"..." ]]
                            </p>
                            <h1>[[ product.store.name ]]</h1>
              
                            
                            <!-- <p class="card-text px-2" style="font-weight: 400; font-size: 14px;">
                              [[ product.title.substring(0,22)+"..." ]]
                            </p> -->
              
              
                            <div class="fw-bold px-2">₦ [[ formatPrice(product.price) ]]</div>
              
                          </div>
                        </div>
                      </a>
                    </div>
                    <!-- <hr> -->
                  </div>
                </section>
              
              
              </div>
    
        </div>

Tutorials

Современный Python: начинаем проект с pyenv и poetry

Настройка проекта Python — виртуальные среды и управление пакетами

Использование requests в Python — тайм-ауты, повторы, хуки

Понимание декораторов в Python

ProcessPoolExecutor в Python: полное руководство

map() против submit() с ProcessPoolExecutor в Python

Понимание атрибутов, словарей и слотов в Python

Полное руководство по slice в Python

Выпуск Django 4.0

Безопасное развертывание приложения Django с помощью Gunicorn, Nginx и HTTPS

Автоматический повтор невыполненных задач Celery

Django REST Framework и Elasticsearch

Докеризация Django с помощью Postgres, Gunicorn и Nginx

Асинхронные задачи с Django и Celery

Релизы безопасности Django: 3.2.4, 3.1.12 и 2.2.24

Выпуски исправлений ошибок Django: 3.2.3, 3.1.11 и 2.2.23

Эффективное использование сериализаторов Django REST Framework

Выпуски безопасности Django: 3.2.2, 3.1.10 и 2.2.22

Выпущенные релизы безопасности Django: 3.2.1, 3.1.9 и 2.2.21

Обработка периодических задач в Django с помощью Celery и Docker

View all tutorials →