Skip to main content
 首页 » 编程设计

python之Django View 在模型更改后不更新

2024年08月21日30kenshinobiy

我正在处理的 Django 项目遇到问题。

我有一个 View ,其中我通过 POST 请求创建了一个模型实例:

class CreatePollView(View): 
    template = "polls/create_poll.html" 
 
    @method_decorator(login_required) 
    def post(self, request): 
        question_text = request.POST['question'] 
        pub_date = now() 
        new_question = Question(question_text=question_text, pub_date=pub_date) 
        new_question.save() 
 
        options_list = request.POST.getlist('options') 
        for option in options_list: 
            option_text = option 
            new_option = Option(option_text=option_text, question=new_question) 
            new_option.save() 
 
        return HttpResponseRedirect(reverse('polls:detail', args=(new_question.id,))) 

这很好用。我可以将问题及其选项添加到数据库中,然后看到它已添加到管理员中。但是,当我随后调用我的 index.html(其中列出了所有问题对象)时,它不会更新。

class IndexView(View): 
    template = loader.get_template('polls/index.html') 
    questions = Question.objects.all() 
    context = { 
        'question_list': questions, 
    } 
 
    def get(self, request): 
        return HttpResponse(self.template.render(self.context, request)) 

和模板:

{% extends 'homepage/base.html' %} 
{% block content %} 
    <div class="row"> 
        <div class="col-md-6 col-md-offset-3"> 
            <h1>All Polls:</h1> 
            <div> 
                {% for question in question_list %} 
                    <p><a href="{{ question.pk }}">{{ question }}</a></p> 
 
                {% endfor %} 
                <a href="new_poll" class="btn btn-primary">New Poll</a> 
            </div> 
        </div> 
    </div> 
{% endblock %} 

当我在 View 中构建错误,然后修复它并再次运行代码时,它会更新列表。 Question.objects.all()

但除此之外,当我发布新模型实例时,模型更改不会显示在这里。谁能告诉我我做错了什么?

编辑:这似乎只发生在基于类的 View 中。当我使用方法 View 时,它运行良好。

def index(request): 
    question_list = Question.objects.all() 
    template = loader.get_template('polls/index.html') 
    context = { 
        'question_list': question_list, 
    } 
    return HttpResponse(template.render(context, request)) 
 
 
def new_poll(request): 
    if request.method == 'POST': 
        question_text = request.POST['question'] 
        pub_date = now() 
        new_question = Question(question_text=question_text, pub_date=pub_date) 
        new_question.save() 
 
        options_list = request.POST.getlist('options') 
        # import pdb 
        # pdb.set_trace() 
        for option in options_list: 
            option_text = option 
            new_option = Option(option_text=option_text, question=new_question) 
            new_option.save() 
 
        return HttpResponseRedirect(reverse('polls:detail', args=(new_question.id,))) 
    else: 
        template = loader.get_template('polls/create_poll.html') 
        context = { 
            'user': request.user 
        } 
        return HttpResponse(template.render(context, request)) 

请您参考如下方法:

Django 被设计成一个长时间运行的进程(加载一次,永远服务),而不是作为一个 CGI 脚本,在每个 HTTP 请求中,所有内容都会重新加载。这意味着在函数外部发生的任何事情(即在模块的顶层,在类语句的主体等)在模块的第一次导入时(每个进程)只执行一次(好吧,实际上就像任何 Python 进程一样 - 这里的重点是它是一个长期运行的过程,而不是一次性脚本)。

所以在这里:

class IndexView(View): 
    template = loader.get_template('polls/index.html') 
    questions = Question.objects.all() 
    context = { 
        'question_list': questions, 
    } 

类主体中的这三个语句在模块的第一次导入时使用 class 语句进行评估。从那时起,这些值将不会在进程生命周期内重新评估,因此您确实为 context['question_list'] 从请求到请求保留相同的结果,直到您终止服务器进程并开始一个新的(在第一次请求后会变得陈旧,等等)。

基于函数的 View 没有问题,因为您的代码会在每个请求上执行,从而产生最新的查询集。

长话短说,首先将这段代码移动到您的类 get 方法中:

class IndexView(View): 
    def get(self, request): 
        template = loader.get_template('polls/index.html') 
        questions = Question.objects.all() 
        context = { 
            'question_list': questions, 
        } 
        return HttpResponse(template.render(context, request)) 

那么你可能想多花点时间了解 django 的 forms , modelforms , shortcuts等等,如果你坚持使用基于类的 View ,那么学习使用 various mixins也是。