【问题标题】:error in django templates at {{form.as_table}} when trying to use Create form尝试使用创建表单时,{{form.as_table}} 的 django 模板出错
【发布时间】:2021-03-24 02:50:29
【问题描述】:

我正在使用 Django 3.1 和 Python 3.7 开发一个用于车队管理的 webApp 项目。 我正在使用模型:

class Driver(Employee):
    supervisor_id = models.ForeignKey('Supervisor', on_delete=models.CASCADE, blank=True, null=True)
    projects = models.ManyToManyField('Client', through='ProjectFleet', blank=True, null=True)
    is_driver=True
    def __str__(self):
        return (self.last_name)

class Client(models.Model):
    client_name = models.CharField(max_length=128, blank=True, null=True)
    client_adress = models.CharField(max_length=128, blank=True, null=True)
    client_logo = models.ImageField(upload_to='ClientsLogos/', max_length=100, blank=True, null=True)
    phone_number1 = PhoneNumberField(blank=True, null=True)
    phone1_label = models.CharField(max_length=128, blank=True, null=True)
    phone_number2 = PhoneNumberField(blank=True, null=True)
    phoneé_label = models.CharField(max_length=128, blank=True, null=True)
    phone_number3 = PhoneNumberField( blank=True, null=True)
    phone3_label = models.CharField(max_length=128, blank=True, null=True)
    client_email1 = models.EmailField(blank=True, null=True)
    email1_label = models.CharField(max_length=128, blank=True, null=True)
    client_email2 = models.EmailField(blank=True, null=True)
    email2_label = models.CharField(max_length=128, blank=True, null=True)
    client_email3 = models.EmailField(blank=True, null=True)
    email3_label = models.CharField(max_length=128, blank=True, null=True)
    drivers = models.ManyToManyField('Driver', through='ProjectFleet')
    def __str__(self):
        return (self.client_name)
class ProjectFleet(models.Model):
    client_id = models.ForeignKey('Client', blank=True, null=True, on_delete=models.SET_NULL)
    drivers = models.ForeignKey('Driver', blank=True, null=True, on_delete=models.SET_NULL)
    def __str__(self):
        return (self.client_id)


class Contract(models.Model):
    client_id = models.ForeignKey('Client', blank=True, null=True, on_delete=models.SET_NULL)
    contract_title = models.CharField(max_length=128, blank=True, null=True)
    contract_details = models.CharField(max_length=512, blank=True, null=True)
    effective_date = models.DateField(auto_now=False, auto_now_add=False, blank=True, null=True)
    expiration_date = models.DateField(auto_now=False, auto_now_add=False, blank=True, null=True)
    def __str__(self):
        return (self.contract_title)

我正在尝试使用的视图:

class DriverCreationView(LoginRequiredMixin, CreateView):
    model = Driver
    fields = ['registration_number','first_name', 'last_name', 'password', 'cni', 'birth_date', 'birth_city', 'picture', 'matricule_cnss', 'driving_licence', 'recruitment_date', 'phone', 'salary', 'Contract_type', 'adress', 'city_id', 'region_id', 'payment_mode', 'bank_address', 'bank_id', 'is_driver', 'vehicle_id', 'supervisor_id', 'projects']
    success_url = reverse_lazy('Drivers_App_Management:all-drivers')

class ClientCreationView(LoginRequiredMixin, CreateView):
    model = Client
    fields = '__all__'
    success_url = reverse_lazy('Drivers_App_Management:all-clients')


class ProjectFleetCreationView(LoginRequiredMixin, CreateView):
    model = ProjectFleet
    fields = '__all__'
    success_url = reverse_lazy('Drivers_App_Management:all-projectsfleet')


class ContractCreationView(LoginRequiredMixin, CreateView):
    model = Contract
    fields = '__all__'
    success_url = reverse_lazy('Drivers_App_Management:all-contracts')

我遇到的问题是当我尝试访问用于创建 Projectfleet 的表单时,这是一个低谷表,也是 Contract 的创建。 每个模板是: projectfleet_form.html

<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Client Creation</title>
  </head>
  <body>
    <h1>This is the Project Fleet Creation form </h1>
    <form class="" action="" method="post">
      {% csrf_token %}
        <table>
          {{ form.as_table }}
        </table>
        <input type="submit" name="" value="submit">
        <input type="submit" onclick="window.location='{% url 'Drivers_App_Management:all-projectsfleet' %}' ; return False;" value="Cancel">
    </form>
  </body>
</html>

contract_form.html

<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Contract Creation</title>
  </head>
  <body>
    <h1>This is the Contract Creation form </h1>
    <form class="" action="" method="post">
      {% csrf_token %}
        <table>
          {{form.as_table}}
          {{ form.contract_title }}
          {{ form.contract_details }}
          {{ form.effective_date }}
          {{ form.expiration_date }}
        </table>
        <input type="submit" name="" value="submit">
        <input type="submit" onclick="window.location='{% url 'Drivers_App_Management:all-contracts' %}' ; return False;" value="Cancel">
    </form>
  </body>
</html>

对于这两个模板,我都会收到一个我不理解的错误:

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/Drivers_App_Management/ProjectFleetCreation

Django Version: 3.1.3
Python Version: 3.7.4
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.gis',
 'django_extensions',
 'phonenumber_field',
 'Drivers_App_Management',
 'django_rename_app']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']


Template error:
In template /home/mohammed/Projects/Transport_Project/Drivers_App_Management/templates/Drivers_App_Management/projectfleet_form.html, error at line 11
   __str__ returned non-string (type NoneType)
   1 : <html lang="en" dir="ltr">
   2 :   <head>
   3 :     <meta charset="utf-8">
   4 :     <title>Client Creation</title>
   5 :   </head>
   6 :   <body>
   7 :     <h1>This is the Project Fleet Creation form </h1>
   8 :     <form class="" action="" method="post">
   9 :       {% csrf_token %}
   10 :         <table>
   11 :            {{ form.as_table }} 
   12 :         </table>
   13 :         <input type="submit" name="" value="submit">
   14 :         <input type="submit" onclick="window.location='{% url 'Drivers_App_Management:all-projectsfleet' %}' ; return False;" value="Cancel">
   15 :     </form>
   16 :   </body>
   17 : </html>
   18 : 

Traceback (most recent call last):
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/core/handlers/base.py", line 202, in _get_response
    response = response.render()
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/response.py", line 105, in render
    self.content = self.rendered_content
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/response.py", line 83, in rendered_content
    return template.render(context, self._request)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/backends/django.py", line 61, in render
    return self.template.render(context)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/base.py", line 170, in render
    return self._render(context)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/base.py", line 162, in _render
    return self.nodelist.render(context)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/base.py", line 988, in render
    output = self.filter_expression.resolve(context)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/base.py", line 671, in resolve
    obj = self.var.resolve(context)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/base.py", line 796, in resolve
    value = self._resolve_lookup(context)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/base.py", line 858, in _resolve_lookup
    current = current()
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/forms.py", line 277, in as_table
    errors_on_separate_row=False,
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/forms.py", line 236, in _html_output
    'field_name': bf.html_name,
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/utils/html.py", line 376, in <lambda>
    klass.__str__ = lambda self: mark_safe(klass_str(self))
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/boundfield.py", line 34, in __str__
    return self.as_widget()
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/boundfield.py", line 97, in as_widget
    renderer=self.form.renderer,
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/widgets.py", line 241, in render
    context = self.get_context(name, value, attrs)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/widgets.py", line 678, in get_context
    context = super().get_context(name, value, attrs)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/widgets.py", line 639, in get_context
    context['widget']['optgroups'] = self.optgroups(name, context['widget']['value'], attrs)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/widgets.py", line 587, in optgroups
    for index, (option_value, option_label) in enumerate(self.choices):
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/models.py", line 1157, in __iter__
    yield self.choice(obj)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/models.py", line 1171, in choice
    self.field.label_from_instance(obj),
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/models.py", line 1240, in label_from_instance
    return str(obj)

Exception Type: TypeError at /Drivers_App_Management/ProjectFleetCreation
Exception Value: __str__ returned non-string (type NoneType)

对于合同表格:

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/Drivers_App_Management/ContractCreation

Django Version: 3.1.3
Python Version: 3.7.4
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.gis',
 'django_extensions',
 'phonenumber_field',
 'Drivers_App_Management',
 'django_rename_app']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']


Template error:
In template /home/mohammed/Projects/Transport_Project/Drivers_App_Management/templates/Drivers_App_Management/contract_form.html, error at line 11
   __str__ returned non-string (type NoneType)
   1 : <html lang="en" dir="ltr">
   2 :   <head>
   3 :     <meta charset="utf-8">
   4 :     <title>Contract Creation</title>
   5 :   </head>
   6 :   <body>
   7 :     <h1>This is the Contract Creation form </h1>
   8 :     <form class="" action="" method="post">
   9 :       {% csrf_token %}
   10 :         <table>
   11 :            {{form.as_table}} 
   12 :           {{ form.contract_title }}
   13 :           {{ form.contract_details }}
   14 :           {{ form.effective_date }}
   15 :           {{ form.expiration_date }}
   16 :         </table>
   17 :         <input type="submit" name="" value="submit">
   18 :         <input type="submit" onclick="window.location='{% url 'Drivers_App_Management:all-contracts' %}' ; return False;" value="Cancel">
   19 :     </form>
   20 :   </body>
   21 : </html>


Traceback (most recent call last):
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/core/handlers/base.py", line 202, in _get_response
    response = response.render()
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/response.py", line 105, in render
    self.content = self.rendered_content
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/response.py", line 83, in rendered_content
    return template.render(context, self._request)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/backends/django.py", line 61, in render
    return self.template.render(context)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/base.py", line 170, in render
    return self._render(context)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/base.py", line 162, in _render
    return self.nodelist.render(context)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/base.py", line 988, in render
    output = self.filter_expression.resolve(context)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/base.py", line 671, in resolve
    obj = self.var.resolve(context)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/base.py", line 796, in resolve
    value = self._resolve_lookup(context)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/template/base.py", line 858, in _resolve_lookup
    current = current()
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/forms.py", line 277, in as_table
    errors_on_separate_row=False,
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/forms.py", line 236, in _html_output
    'field_name': bf.html_name,
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/utils/html.py", line 376, in <lambda>
    klass.__str__ = lambda self: mark_safe(klass_str(self))
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/boundfield.py", line 34, in __str__
    return self.as_widget()
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/boundfield.py", line 97, in as_widget
    renderer=self.form.renderer,
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/widgets.py", line 241, in render
    context = self.get_context(name, value, attrs)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/widgets.py", line 678, in get_context
    context = super().get_context(name, value, attrs)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/widgets.py", line 639, in get_context
    context['widget']['optgroups'] = self.optgroups(name, context['widget']['value'], attrs)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/widgets.py", line 587, in optgroups
    for index, (option_value, option_label) in enumerate(self.choices):
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/models.py", line 1157, in __iter__
    yield self.choice(obj)
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/models.py", line 1171, in choice
    self.field.label_from_instance(obj),
  File "/home/mohammed/anaconda3/envs/myEnv/lib/python3.7/site-packages/django/forms/models.py", line 1240, in label_from_instance
    return str(obj)

Exception Type: TypeError at /Drivers_App_Management/ContractCreation
Exception Value: __str__ returned non-string (type NoneType)

我想提一下,例如,如果我使用带有字段名称 {{form.contract_title}} 的表单,但我得到它们时没有标签。

【问题讨论】:

    标签: python-3.x django django-forms django-templates


    【解决方案1】:

    您设法欺骗自己,认为通过模型中的可空外键是正常的。它不是。在任何多对多关系中,关系模型的两个外键都应该设置,否则没有关系,模型中不需要一行。

    这会导致模型选择带有标签的 None 值,这就是它所抱怨的。

    根本问题

    根本问题是您的__str__() 两种模型的方法。顾名思义,它应该总是返回一个字符串,但你允许它返回 None。

    改为:

    def __str__(self) -> str:
        return self.contract_title or ""
    

    但是你真的应该重新审视你的模型设计。拥有带有null=True 的字段有其用途,但对于没有unique=True 的CharField,它只会导致没有任何好处的问题。

    【讨论】:

    • 感谢您的解释,我了解项目队的问题,但是当我尝试显示 frm 以创建新合同时也出现错误,并且我在那里有一个外键。跨度>
    • 非常感谢,是的,我同意你的看法。只是因为数据库尚未加载,我需要测试应用程序,所以我将字段设置为 null=True,但我会更改它。
    猜你喜欢
    • 2017-08-18
    • 1970-01-01
    • 2011-08-06
    • 2021-04-18
    • 2016-10-04
    • 1970-01-01
    • 2017-08-07
    • 1970-01-01
    • 2022-08-22
    相关资源
    最近更新 更多