Я работаю над проектом веб-приложения для управления автопарком, используя Django 3.1 и Python 3.7. Я использую модели:
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_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}}, например, но я получил их без метки.
Вам удалось обмануть себя, заставив думать, что внешние ключи, допускающие значение NULL, в сквозной модели — это разумная вещь. Это не. В любом отношении ManyToMany должны быть установлены оба внешних ключа к моделям отношений, иначе нет никакого отношения и нет необходимости в строке в модели.
Это приводит к выбору модели со значениями None
для меток, на что он жалуется.
Основная проблема заключается в вашем методе __str__()
для обеих моделей. Как видно из названия, он всегда должен возвращать строку, но вы разрешаете ему возвращать None.
Изменить на:
def __str__(self) -> str:
return self.contract_title or ""
Но вам действительно следует пересмотреть дизайн вашей модели. Наличие полей с null=True
имеет свои преимущества, но для CharField без unique=True
это только вызывает проблемы без каких-либо преимуществ.
Большое спасибо, да, я с вами согласен. это просто потому, что база данных еще не загружена, и мне нужно протестировать приложение, поэтому я установил поля на null=True
, но я изменю это.
Спасибо за объяснение, я понимаю проблему для парка проекта, но я получаю ошибки также, когда пытаюсь отобразить frm для создания нового контракта, и у меня там есть внешний ключ.