使用ModelForm保存大量对象

时间:2015-06-23 21:59:26

标签: python django django-forms

我需要保存大量的Member对象。我试过使用ModelForm

https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#modelform

models.py

from django.contrib.auth.models import User


class Member(models.Model):
    project = models.ForeignKey('projects.Project')
    user = models.ForeignKey(User)
    created = CreationDateTimeField(_('created'))
    roles = models.ManyToManyField('users.Role')

class Role(models.Model):
    name = models.CharField(_("Name"), max_length=30)
    permissions = models.TextField(_("Permissions"))

forms.py

class ProjectAddMembersForm(forms.ModelForm):
    user = forms.ModelMultipleChoiceField(
        widget=CheckBoxMultipleSelect(),
        queryset=User.objects.all(),
    )
    roles = forms.ModelMultipleChoiceField(
        widget=CheckBoxMultipleSelect(),
        queryset=Role.objects.all(),
    )

    class Meta:
        model = Member
        fields = ('user', 'roles')

views.py

class ProjectMembershipView(LoginRequiredMixin, generic.View):
    template_name = "projects/memberships.html"
    form_class = forms.ProjectAddMembersForm

    def post(self, request, *args, **kwargs):
    """Add users to members of the project"""
        slug = self.kwargs.get('slug', None)
        url = reverse("settings_members", kwargs={'slug': slug})
        project = get_object_or_404(Project, identifier=slug)

        form = self.form_class(request.POST)
        if form.is_valid():
            return HttpResponseRedirect(url)

        return render(request, self.template_name, {'form': form})

以格式发送的POST数据:

Variable               Value
u'csrfmiddlewaretoken' ....
u'roles'               [u'1']
u'user'                [u'1', u'3']

我收到了错误。

Cannot assign "[<User: discort>, <User: test>]": "Member.user" must be a "User" instance.

因为我将对象列表传递给用户字段

django/db/models/fields/__init__.py in save_form_data
874.        setattr(instance, self.name, data)
Local       vars
Variable    Value
instance    Error in formatting: RelatedObjectDoesNotExist: Member has no user.
self        <django.db.models.fields.related.ForeignKey: user>
data        [<User: discort>, <User: test>]

如何将大量具有角色列表的用户保存到数据库。

我在views.py中写了伪代码我想做什么:

# Get ids of the users and ids of the roles
users = request.POST.getlist("user")
roles = request.POST.getlist("roles")
# For each user create unique member with the given roles
# Save all the members to the database

我应该将ModelForm或Form与自定义save()方法一起使用吗?

1 个答案:

答案 0 :(得分:0)

我拒绝了ModelForm并为Form

编写了自定义save()方法

views.py

def post(self, request, *args, **kwargs):
    """
    Add users to members of the project
    """
    slug = self.kwargs.get('slug', None)
    url = reverse("settings_members", kwargs={'slug': slug})
    project = get_object_or_404(Project, identifier=slug)

    form = self.form_class(request.POST)
    if form.is_valid():
        users_ids = request.POST.getlist("user")
        roles_ids = request.POST.getlist("roles")
        kwargs = dict(users=users_ids, roles=roles_ids, project=project)

        form.save(**kwargs)
        return HttpResponseRedirect(url)

    return render(request, self.template_name, {'form': form})

forms.py

class ProjectAddMembersForm(forms.Form):
    users = forms.ModelMultipleChoiceField(
         widget=CheckBoxMultipleSelect(),
         queryset=User.objects.all(),
    )
    roles = forms.ModelMultipleChoiceField(
         widget=CheckBoxMultipleSelect(),
         queryset=Role.objects.all(),
    )

    def __init__(self, *args, **kwargs):
        super(ProjectAddMembersForm, self).__init__(*args, **kwargs)

    def save(self, **kwargs):
        users = User.objects.filter(pk__in=kwargs.get('users', None))
        roles = Role.objects.filter(pk__in=kwargs.get('roles', None))
        project = kwargs.get('project', None)

        for user in users:
            member, created = Member.objects.get_or_create(project=project, user=user)
            if created:
                for role in roles:
                    member.roles.add(role)