Django使用inlineformset复制数据库查找

时间:2019-01-20 20:41:43

标签: python django database duplicates

我需要帮助来解决有关inlineformset中每个表单的重复数据库查询的问题。我有一个页面,用户可以在其中添加和编辑作者的书籍。

models.py

from django.db import models
class Author(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=100)

class Book(models.Model):
    id = models.AutoField(primary_key=True)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)
    category_idcategory = models.ForeignKey(Category, models.DO_NOTHING)

class Category(models.Model):
    name = models.CharField(max_length=100)

forms.py

from django import forms
class BookForm(forms.ModelForm):
    class Meta:
        model = Book
        fields = '__all__'

views.py

instance = get_object_or_404(Author, id=id)
form = inlineformset_factory(Author, Book, form=BookForm, can_delete=True, extra=5)
formset = form(request.POST or None, instance=instance)

if request.method == "POST":
    if formset.is_valid():
        instanceForm = formset.save(commit=False)
        for obj in instanceForm:
            obj.save()
        for obj in formset.deleted_objects:
            obj.delete()
        return HttpResponseRedirect(URL)

运行模板时,它将对表单集中的每个表单执行对类别模型的数据库查询。如何防止重复?我不知道将select_related或prefetch_related放在哪里。如果Book模型的实例数量增加,则页面加载时间将变得非常缓慢。

template.html

<table class="table table-sm">
{{ formset.management_form }}
    <thead>
        <td>Title</td>
        <td>Category</td>
        <td>delete</td>
    </thead>
    <tbody>
    {% for obj in formset %}
    {{ obj.id }}
        <tr>
            <td>{{ obj.title }}</td>
            <td>{{ obj.category_idcategory }}</td>
            <td>{{ obj.DELETE }}</td>
       </tr>
    {% endfor %}
    </tbody>
</table>

1 个答案:

答案 0 :(得分:0)

您可以像这样更改表单集的查询集:

#include <iterator>

template<class Derived, class Type>
class std_bidirectional_iterator : public std::iterator<std::bidirectional_iterator_tag, Type>
{
    virtual Derived & operator=(const Derived & it) = 0;            // Copy Assignment Operator

    virtual reference operator*(void) = 0;                          // De-Reference Operator (Returns reference)

    virtual pointer operator->(void) = 0;                           // De-Reference Operator (Returns pointer)

    virtual Derived & operator++(void) = 0;                         // Pre-Fix ++
    virtual Derived operator++(int) = 0;                            // Post-Fix ++

    virtual Derived & operator--(void) = 0;                         // Pre-Fix --
    virtual Derived operator--(int) = 0;                            // Post-Fix --

    virtual bool operator==(const Derived & it) const = 0;          // Equal To Operator
    virtual bool operator!=(const Derived & it) const = 0;          // Not Equal To Operator
};

然后在您的工厂方法调用中:

class InlineBookFormSet(BaseInlineFormSet):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Here is where to put the select_related.
        self.queryset = Book.objects.select_related('category_idcategory').all()