Как работать с внешним ключом с множественным выбором
Привет всем я пытаюсь достичь выбора нескольких автомобилей с помощью отношения внешнего ключа, потому что нам нужно хранить данные в нескольких строках, я пробовал с множеством способов, но это не эффективно в соответствии с нашими требованиями, поэтому я пытаюсь решить это с помощью внешнего ключа, пожалуйста, помогите мне.
models.py
class Car_team(BaseModel):
team = models.ForeignKey(
Team,
models.CASCADE,
verbose_name='Team',
null=True,
)
car=models.ForeignKey(
Car,
models.CASCADE,
verbose_name='Car',
null=True)
city =models.ForeignKey(
City,
models.CASCADE,
verbose_name='City',
)
start_date=models.DateField(null=True, blank=True)
end_date=models.DateField(null=True, blank=True)
forms.py
class CarTeamForm(forms.ModelForm):
start_date=forms.DateField(initial=datetime.date.today, label='Start Date')
car = forms.ModelMultipleChoiceField(queryset=Car.objects.all(), required=True, widget=forms.CheckboxSelectMultiple)
class Meta:
model = Car_team
fields = ['car','team','city','start_date']
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(CarTeamForm, self).__init__(*args, **kwargs)
self.fields['start_date'].widget.attrs['readonly'] = True
widgets = {
'car': forms.CheckboxSelectMultiple(attrs={'class': 'form-control select2'}),
}
views.py
def add_carteam(request, city_id=None, id=None):
if id is not None:
carteam = get_object_or_404(Car_team, city_id=city_id, pk=id)
else:
carteam = None
if request.method == 'POST':
form = CarTeamForm(request.POST, request.FILES,instance=carteam)
if form.is_valid():
car = form.cleaned_data['car']
team = form.cleaned_data['team']
start_date = Car_team.objects.filter(car__in=car).values_list('start_date', flat=True).filter(end_date__isnull=True)
# if start_date:
# messages.error(request,'Car already assigned to another team!')
query = Car_team.objects.filter(car__in=car).exists()
query_set = Car_team.objects.filter(car__in=car).values_list('team', flat=True)
team_name = Team.objects.filter(pk__in=query_set).values_list('name', flat=True)
car_id = Car_team.objects.filter(car__in=car).values_list('car', flat=True)
car_number=Car.objects.filter(pk__in=car_id).values_list('car_number', flat=True)
if query_set and start_date:
messages.error(request,'Car already assigned to team {} {}!'.format(team_name,car_number))
# if query:
# messages.error(request,'Car already assigned to another team!')
else:
#print(start_query)
form.save()
messages.success(request,'Assign Cars To Teams data added successfully!')
return redirect('/fleet/carteam_list')
else:
messages.error(request,'Please correct the error below.',form.errors)
else:
form = CarTeamForm(instance=carteam)
context = {
'menu_car_management': 'active',
'submenu_carteam': 'active',
'form': form,
'id': id,
'city_id': city_id,
}
return render(request, 'hiringprocess/addcarteam_form.html', context=context)
addcarteam_form.html
<section class="content">
<div class="container-fluid">
<form role="form" method="post" enctype="multipart/form-data" action="/fleet/addcarteam/{{city_id}}/add" autocomplete="off">
{% csrf_token %}
<div class="row">
<div class="col-xs-12">
<div class="box box-widget">
<div class="box-body">
<div class="col-md-6">
{{ form.team|as_crispy_field}}
</div>
<div class="col-md-6">
{{ form.city|as_crispy_field}}
</div>
<div class="col-md-6">
{{ form.start_date|as_crispy_field}}
</div>
<div class="col-md-12 scroll">
{% for i in form.car %}
<div class="col-md-3">
{{i}}
</div>
{% endfor %}
</div>
</div> -->
</div>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary" style="margin-bottom:20px;">
<span class="glyphicon glyphicon-ok-circle"></span>
<span id="btn_txt">Save</span>
</button>
</form>
</div>
</section>
Ошибка вывода
ERROR Internal Server Error: /fleet/addcarteam/1/add
Traceback (most recent call last):
File "C:\Users\HI\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\HI\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\HI\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\HI\AppData\Local\Programs\Python\Python37\lib\site-packages\django\contrib\auth\decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "E:\20_jan_2022_everest\everest_jarvis\fleet\views.py", line 3879, in add_carteam
if form.is_valid():
File "C:\Users\HI\AppData\Local\Programs\Python\Python37\lib\site-packages\django\forms\forms.py", line 185, in is_valid
return self.is_bound and not self.errors
File "C:\Users\HI\AppData\Local\Programs\Python\Python37\lib\site-packages\django\forms\forms.py", line 180, in errors
self.full_clean()
File "C:\Users\HI\AppData\Local\Programs\Python\Python37\lib\site-packages\django\forms\forms.py", line 383, in full_clean
self._post_clean()
File "C:\Users\HI\AppData\Local\Programs\Python\Python37\lib\site-packages\django\forms\models.py", line 398, in _post_clean
self.instance = construct_instance(self, self.instance, opts.fields, opts.exclude)
File "C:\Users\HI\AppData\Local\Programs\Python\Python37\lib\site-packages\django\forms\models.py", line 60, in construct_instance
f.save_form_data(instance, cleaned_data[f.name])
File "C:\Users\HI\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\fields\__init__.py", line 853, in save_form_data
setattr(instance, self.name, data)
File "C:\Users\HI\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\fields\related_descriptors.py", line 211, in __set__
self.field.remote_field.model._meta.object_name,
ValueError: Cannot assign "<QuerySet [<Car: HR38AB6029>, <Car: HR38AB6822>]>": "Car_team.car" must be a "Car" instance.
ERROR "POST /fleet/addcarteam/1/add HTTP/1.1" 500 114584
Вы неправильно понимаете ForeignKey. CarTeam.car может представлять один и только один автомобиль, и поэтому виджет CheckboxSelectMultiple неуместен. Используйте значение по умолчанию, или, возможно, RadioSelect.
Если вы ожидаете, что он будет представлять несколько автомобилей, то это либо ManyToMany, либо вы располагаете их спина к спине, и у вас должен быть car_team ForeignKey на модели Car. Набор автомобилей, относящихся к экземпляру car_team, доступен через этот экземпляр как указанное имя related_name, которое по умолчанию равно car_set.
Для выбора нескольких автомобилей вам понадобится другая форма (бесплатная: queryset Car.objects.filter( car_team__isnull=True ) и затем для каждого установите car_team на тот, которым вы управляете, и сохраните его.
Вы можете обрабатывать несколько форм в одном представлении. Используйте префикс формы, если имена полей будут противоречить друг другу.