禁止直接赋值给多对多集合的前端。使用 manager.set() 代替

Direct assignment to the forward side of a many-to-many set is prohibited. Use manager.set() instead

在 Django 表单中使用 ManyToManyField 时出现错误,在 managar 字段中使用 ManyToManyField 时出现此错误。当我使用具有相同代码的外键时,它工作正常 我需要在 manytomanyfield 上工作,请帮助我

models.py

class Team(BaseModel):
    Team_name = models.CharField(max_length=30)
    Logo=models.ImageField(upload_to='img/%Y/%m/%d',height_field=None, width_field=None, max_length=100, default=None)
    Team_manager_photo=models.ImageField(upload_to='img/%Y/%m/%d',null=True, blank=True)
    manager=models.ManyToManyField(User)
    city =models.ForeignKey(
        City,
        models.CASCADE,
        verbose_name='City',
    )
    

form.py 这是添加和编辑数据的表单

class TeamForm(forms.Form):
    Team_name = forms.CharField(max_length=30,required=True)
    city = forms.ModelChoiceField(required=True, queryset=City.objects.all())
    Logo=forms.ImageField(required=False)
    Team_manager_photo=forms.ImageField(required=False)
    manager= forms.ModelMultipleChoiceField(required=False, queryset=User.objects.all(),widget=forms.SelectMultiple(attrs={'class': 'form-control'}))

    def __init__(self, *args, **kwargs):
        # city_id = kwargs.pop("city_id")
        self.request = kwargs.pop('request', None)
        super(TeamForm, self).__init__(*args, **kwargs)

views.py 添加和编辑数据的功能

def add_edit_team(request, city_id=None, id=None):
    if id:
        team=Team.objects.get(pk=id)
    if request.method == "POST":
        form=TeamForm(request.POST, request.FILES, request=request)
        if form.is_valid():
            Team_name=form.cleaned_data['Team_name']
            Logo=form.cleaned_data['Logo']
            Team_manager_photo=form.cleaned_data['Team_manager_photo']
            manager=form.cleaned_data['manager']
            city=request.POST['city']

            if id:
                team.Team_name=Team_name
                team.Logo=Logo
                team.Team_manager_photo=Team_manager_photo
                team.manager=manager
                team.city_id=city
                team.save()
                messages.success(request,'Team data updated successfully!')
                return redirect('/fleet/team_list')
            else:
                s = Team(Team_name=Team_name,Logo=Logo,Team_manager_photo=Team_manager_photo,manager=manager,city_id = city)
                s.save()
                messages.success(request,'Team data added successfully!')
                return redirect('/fleet/team_list')
    elif id:        
        form=TeamForm(initial={'Team_name':team.Team_name,'Logo':team.Logo,'Team_manager_photo':team.Team_manager_photo,'manager':team.manager,'city':team.city})

    else:
        form=TeamForm()

    context = {
        'menu_car_management': 'active',
        'submenu_team': 'active',
        'form': form,
        'id': id,
        'city_id': city_id,
    }
    return render(request, "hiringprocess/team_edit.html", context=context)

添加新记录时输出错误

ERROR Internal Server Error: /fleet/team/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:_jan_2022_everest\everest_jarvis\fleet\views.py", line 3636, in add_edit_team
    s = Team(Team_name=Team_name,Logo=Logo,Team_manager_photo=Team_manager_photo,manager=manager,city_id = city)  
  File "C:\Users\HI\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\base.py", line 496, 
in __init__
    _setattr(self, prop, kwargs[prop])
  File "C:\Users\HI\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\fields\related_descriptors.py", line 538, in __set__
    % self._get_set_deprecation_msg_params(),
TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use manager.set() instead.  
ERROR "POST /fleet/team/1/add HTTP/1.1" 500 95625

使用 ManyToMany 时,您需要获取 User 对象,然后将其添加到 manager 字段。创建实例时不能将对象添加到 ManyToManyField。看看文档。 https://docs.djangoproject.com/en/2.2/topics/db/examples/many_to_many/

def add_edit_team(request, city_id=None, id=None):
    if id:
        team=Team.objects.get(pk=id)
    if request.method == "POST":
        form=TeamForm(request.POST, request.FILES, request=request)
        if form.is_valid():
            Team_name=form.cleaned_data['Team_name']
            Logo=form.cleaned_data['Logo']
            Team_manager_photo=form.cleaned_data['Team_manager_photo']
            manager=form.cleaned_data['manager']
            city=request.POST['city']
           # Am assuming the User model has a manage field, but you can otherwise filter 
           # by any field in the user model.
            managar_of_team = User.objects.filter(manager__in=manager)
            if id:
                team.Team_name=Team_name
                team.Logo=Logo
                team.Team_manager_photo=Team_manager_photo
                team.manager= managar_of_team
                team.city_id=city
                team.save()
                messages.success(request,'Team data updated successfully!')
                return redirect('/fleet/team_list')
            else:
                s = Team(Team_name=Team_name,Logo=Logo,Team_manager_photo=Team_manager_photo,manager= managar_of_team,city_id = city)
                s.save()
                messages.success(request,'Team data added successfully!')
                return redirect('/fleet/team_list')
    elif id:        
        form=TeamForm(initial={'Team_name':team.Team_name,'Logo':team.Logo,'Team_manager_photo':team.Team_manager_photo,'manager':team.manager,'city':team.city})

    else:
        form=TeamForm()

    context = {
        'menu_car_management': 'active',
        'submenu_team': 'active',
        'form': form,
        'id': id,
        'city_id': city_id,
    }
    return render(request, "hiringprocess/team_edit.html", context=context)

如果imagemanager(s)不是必须的,需要在对应的model字段上设置blank=True,可能重命名为[=11比较好=] 到 managers 因为这暗示我们正在与 多个 经理合作:

from django.conf import settings

class Team(BaseModel):
    # …
    Logo=models.ImageField(upload_to='img/%Y/%m/%d',height_field=None, width_field=None, max_length=100, default=None<strong>, blank=True</strong>)
    <b>managers</b> = models.ManyToManyField(settings.AUTH_USER_MODEL<b>, blank=True</b>)
    # …

我还建议使用 ModelFormModelForm 可以删除大量样板代码,从而使视图更小且更易于实现:

from django import forms

class TeamForm(forms.<strong>ModelForm</strong>):
    class Meta:
        <strong>model = Team</strong>
        <strong>fields = '__all__'</strong>
        widgets = {
            'managers': forms.SelectMultiple(attrs={'class': 'form-control'})
        }

因此我们不需要手动定义任何表单字段:Django 将从 Team 模型派生表单字段。

在那种情况下,视图可以重写为:

from django.shortcuts import get_object_or_404

def add_edit_team(request, city_id=None, id=None):
    if id is not None:
        team = get_object_or_404(Team, city_id=city_id, pk=id)
    else:
        team = None
    if request.method == 'POST':
        form = TeamForm(request.POST, request.FILES<strong>, instance=team</strong>)
        if form.is_valid():
            <strong>form.save()</strong>
            if team is not None:
                messages.success(request,'Team data updated successfully!')
            else:
                messages.success(request,'Team data added successfully!')
            return redirect('/fleet/team_list')
    else:
        form = TeamForm(<strong>instance=team</strong>)
    context = {
        'menu_car_management': 'active',
        'submenu_team': 'active',
        'form': form,
        'id': id,
        'city_id': city_id,
    }
    return render(request, 'hiringprocess/team_edit.html', context=context)

就是这样:表单将自动创建或更新包装在表单中的实例并进行必要的更改(对模型字段和 many-to-many 关系)。


Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.