简体   繁体   English

Django表单不在生产服务器上呈现 - 使用testserver在本地工作正常,并且单元测试在生产服务器上传递

[英]Django forms not rendering on production server - work fine locally with testserver, and unit tests pass on production server

This might be the strangest error I have ever come accross in my short time as a developer. 这可能是我作为开发人员在短时间内遇到的最奇怪的错误。 I have a form that renders perfectly well on my local machine, but the exact same code fails to render on the server. 我有一个在我的本地机器上完美呈现的表单,但完全相同的代码无法在服务器上呈现。

I have a form, that looks like this: 我有一个表单,看起来像这样:

表格的工作版本

Nothing fancy, just a few input fields and a submit button. 没什么好看的,只有几个输入字段和一个提交按钮。

How did I create it? 我是如何创建它的? Well firstly there's a form: 首先,有一个表格:

from django import forms
from django.forms.extras.widgets import SelectDateWidget
from blog.models import BlogPost

EMPTY_FIELD_ERROR = "You cannot submit a blog post with no %s"


class DateInput(forms.DateInput):
    input_type = 'date'



class PlainTextarea(forms.Textarea):

    def build_attrs(self, extra_attrs=None, **kwargs):
        attrs = super(PlainTextarea, self).build_attrs(extra_attrs, **kwargs)
        if "cols" in attrs: del attrs["cols"]
        if "rows" in attrs: del attrs["rows"]
        return attrs



class BlogPostForm(forms.models.ModelForm):


    class Meta:
        model = BlogPost
        fields = ("title", "date", "body", "visible")
        widgets = {
         "title": forms.fields.TextInput(attrs={
          "class": "pure-u-1-1 pure-u-md-19-24"
         }),
         "date": DateInput(),
         "body": PlainTextarea(attrs={
          "class": "pure-u-1-1 pure-u-md-19-24"
         }),
         "visible": forms.CheckboxInput(attrs={
          "class": "pure-u-1-24"
         })
        }
        error_messages = {
         "title": {"required": EMPTY_FIELD_ERROR % "title"},
         "date": {"required": EMPTY_FIELD_ERROR % "date"},
         "body": {"required": EMPTY_FIELD_ERROR % "body"}
        }

In the new_post view, if it detects that the request is a GET request, I simply make an instance of this form, and pass it to the new_post template: 在new_post视图中,如果它检测到请求是GET请求,我只需创建此表单的实例,并将其传递给new_post模板:

def new_post_page(request):
    if request.method == "POST":
        form = BlogPostForm(request.POST)
        if form.is_valid():
            BlogPost.objects.create(
             title=request.POST["title"].strip(),
             date=datetime.datetime.strptime(
              request.POST["date"], "%Y-%m-%d"
             ).date(),
             body=request.POST["body"].strip(),
             visible=request.POST.get("visible") is not None
            )
            return redirect("/")
        else:
            return render(request, "new_post.html", {"form": form})
    form = BlogPostForm()
    return render(request, "new_post.html", {"form": form})

And here's a section of the template: 这是模板的一部分:

<form method="POST" class="pure-form pure-form-aligned">
  <div class="pure-g">
    <div class="pure-u-1-1 formrow">
      <label for="{{ form.title.id_for_label }}" class="pure-u-1-1 pure-u-md-4-24">Title:</label>
      {{ form.title }}
      {% if form.title.errors %}
      <div class="error">
        {{ form.title.errors }}
      </div>
      {% endif %}
    </div>
    <div class="pure-u-1-1 formrow">
      <label for="{{ form.date.id_for_label }}" class="pure-u-1-1 pure-u-md-4-24">Date:</label>
      {{ form.date }}
      {% if form.date.errors %}
      <div class="error">
        {{ form.date.errors }}
      </div>
      {% endif %}
    </div>

This all works fine on my own machine (MacBook, El Capitain, Python3, Django 1.8.4), but when I deploy the code to the server, I get this: 这一切都可以在我自己的机器上运行(MacBook,El Capitain,Python3,Django 1.8.4),但是当我将代码部署到服务器时,我得到了这个:

不工作!

Inspecting the HTML shows that the {{form.title}} tags have not rendered. 检查HTML显示{{form.title}}标记未呈现。 But everything is the same! 但一切都是一样的! Well mostly everything. 好吧一切都好。 Obviously some settings are different on the server such as Debug being set to False. 显然,服务器上的某些设置是不同的,例如Debug被设置为False。 I also use a postgres database on the server, and an SQLite database locally. 我还在服务器上使用postgres数据库,在本地使用SQLite数据库。

To make things even more maddening, I have unit tests, including tests that the new_page view is rendering the form - and they pass on the server! 为了让事情变得更加令人抓狂,我进行了单元测试,包括new_page视图渲染表单的测试 - 并且它们在服务器上传递! I even started a Django shell on the server, manually passed a request to the new_page view, printed the HTML, and the input HTML was there ! 我甚至在服务器上启动了一个Django shell,手动将请求传递给new_page视图,打印HTML, 输入HTML就在那里

Some information that might be useful: 一些可能有用的信息:

  • The server uses nginx, which sends requests to gunicorn. 服务器使用nginx,它向gunicorn发送请求。 The OS is Ubuntu 14.04. 操作系统是Ubuntu 14.04。
  • The form was rendering perfectly well back when it was all HTML, before I connected it to a Django form 在将它连接到Django表单之前,表单在完全是HTML时完全呈现
  • I have applied all migrations - there were no new ones to apply but a migration happens automatically whenever I deploy. 我已经应用了所有迁移 - 没有新的迁移,但每次部署时都会自动进行迁移。

Please help this Django novice? 请帮助这个Django新手?

UPDATE UPDATE

I have tried using the django testserver in place of gunicorn, and that renders the form correctly, so it could be a problem with gunicorn? 我尝试使用django测试服务器代替gunicorn,这使得表单正确,所以它可能是gunicorn的问题?

In case another poor soul ends up here. 如果另一个可怜的灵魂在这里结束。 Check that your packages (pip freeze) are the same locally and on the server. 检查您的软件包(pip freeze)在本地和服务器上是否相同。 I had django-filter==0.15.0 locally and django-filter==0.10.0 on the server which was causing this exact issue with no errors being raised. 我在本地有django-filter == 0.15.0,在服务器上有django-filter == 0.10.0导致这个问题没有引发错误。

So, I have resolved the problem. 所以,我已经解决了这个问题。 Unfortunately I'm not entirely sure how. 不幸的是,我不完全确定如何。

As I mentioned in my update, turning off gunicorn and using the django test server instead fixed the issue. 正如我在更新中提到的那样,关闭gunicorn并使用django测试服务器来修复问题。 I shut down the testserver and fired up gunicorn again, and... the forms were still rendering correctly. 我关闭了测试服务器并再次启动了gunicorn,并且...表单仍然正确呈现。

My suspicion is that restarting gunicorn was all that was needed. 我怀疑是需要重新启动gunicorn。 I don't know why, or if that was definitely what fixed it. 我不知道为什么,或者如果那肯定是什么修复它。 Oh well. 那好吧。

I had the same issue when I deployed my django project to AWS EC2. 当我将django项目部署到AWS EC2时,我遇到了同样的问题。

If you've followed Nginx gunicorn and Django tutorials your best option is to reboot the EC2 and then restart the gunicorn server. 如果您已经关注过Nginx gunicorn和Django教程,那么您最好的选择是重新启动EC2然后重新启动gunicorn服务器。 This has solved my issue. 这解决了我的问题。

You should restart your web sever every time you deploy - that will make sure you are running the latest code for your app. 您应该在每次部署时重新启动Web服务器 - 这将确保您运行应用程序的最新代码。 It's very deceptive because it will correctly pull the html templates, but not run the code that renders the content for the templates (that's why you're seeing your labels which are hard-coded but not the text inputs which are rendered dynamically). 这是非常具有欺骗性的,因为它会正确地拉出html模板,但不会运行为模板呈现内容的代码(这就是为什么你看到你的标签是硬编码但不是动态渲染的文本输入)。

I use Apache on Ubuntu and this gets me every once in a while when I've been up all night debugging something...Always restart your server when you deploy fresh code: 我在Ubuntu上使用Apache,这让我每隔一段时间就会整夜调试一下......总是在部署新代码时重新启动服务器:

sudo service apache2 restart

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在生产服务器上导入数据时出错-在本地工作正常 - Error importing data on production server- locally works fine django在生产服务器上(ubuntu) - django on production server(ubuntu) Django登录自定义身份验证在本地有效,但不能在生产服务器上使用 - Django Login Custom Auth works locally but not on production server 为什么我的 Django 登录可以在开发服务器上运行而不是在生产服务器上运行? - Why does my Django login work on development server but not production server? 烧瓶重定向在生产服务器上附加get%20 /%20HTTP / 1.1)uri。 在当地工作良好 - Flask redirect appends get%20/%20HTTP/1.1)uri on production server. Working fine locally Django生产服务器上的FieldDoesNotExist错误 - FieldDoesNotExist error on Django production server 在生产中使用带有Django的Sql Server - Using Sql Server with Django in production 为什么 Django/Python 请求在生产服务器上不起作用? - Why Django/Python request doesn't work from production server? 如何在生产数据库上运行django单元测试? - How to run django unit-tests on production database? 某些 python 库未加载到我的 Django 生产应用程序中,但在本地服务器中加载正常 - Certain python libraries are not loading in my Django application in production, but load fine in local server
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM