简体   繁体   中英

Is there a way to isolate a foreign key from its related model using django?

I am building a django website that displays the prices of items in a shop. Each item belongs to a category so I mande category a foreign key that can have one or more items.

`class Category(models.Model):
     category = models.CharField(max_length=64)

     def __str__(self):
        return self.category

class ShopItem(models.Model):
    itemName = models.CharField(max_length=64)
    price = models.IntegerField()
    category = models.ForeignKey(Category, on_delete=models.CASCADE)

    def __str__(self):
        return self.itemName`

However, in the html, I am unable to obtain both the category and the shop item

I tried the following...

`---snip---

    {% used_category = [] %}
    {% for item in shopitem_list %}
        {% if item.category not in used_category %}
            <tr>
                <td>item.category</td>
                <td></td>
                <td></td>
            </tr>
            <tr>
                {% for rel_item in shopitem_list %}
                    {% if rel_item.category == item.category %}
                        <td></td>
                        <td>rel_item.itemName</td>
                        <td>rel_item.category</td>
                    {% endif %}
                {% enfor %}
            </tr>
        {% endif %}
    {% endfor %}`

I was hoping this would help me create a table where all the items are sorted below their respective categories but I got an error instead:

TemplateSyntaxError at / Invalid block tag on line 18: 'used_category', expected 'endblock'. Did you forget to register or load this tag?

You can't create and update a list within the template, but you can prepare the data in the view function, then iterate over your items differently.

Start by making sure the categories are in your template context. To avoid n+1 queries, prefetch the related items also. Let's say your view looks like this (updated):

from django.shortcuts import render

from .models import Category


def items_list(request):
    context = {
        "categories": Category.objects.exclude(shop_items=None).prefetch_related(
            "shop_items"
        )
    }
    return render(request, "my_template.html", context)

Then in the template iterate over the categories:

    {% for category in categories %}
            <tr>
                <td colspan="3">{{ category.category }}</td>
            </tr>
            <tr>
                {% for item in category.shop_items %}
                        <td></td>
                        <td>{{ item.itemName }}</td>
                        <td>{{ item.price }}</td>
                {% enfor %}
            </tr>
    {% endfor %}

NB The related name shop_items may not work here. To make sure it does, you can manually set the related_name on your foreign key. At the same time I would suggest changing itemName to just name :

class ShopItem(models.Model):
    name = models.CharField(max_length=64)
    price = models.IntegerField()
    category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="shop_items")

    def __str__(self):
        return self.name

You need to create a view function which will pass the required Models information to the Template, thus completing the Model - View - Template (MVT) method which django runs on.

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