为多对多关系形成、创建和更新视图

Form, Create and Update View for Many-To-Many Relationship

这是我在这里的第一个问题,我正在写这篇文章是因为我对这个很生气,即使在阅读了文档和这里的很多答案之后也是如此。非常感谢,抱歉我的英语不好!

我有这些型号:

class Profile(models.Model):
    name = models.CharField(max_length = 255, blank = False)
    user = models.ForeignKey(User, blank = True, null = True)

class Category(models.Model):
    name = models.CharField(max_length = 50, blank = False)

class ProfileCategory(models.Model):
    profile = models.ForeignKey(Profile)
    category = models.ForeignKey(Category)

    class Meta:
        unique_together = ('profile', 'category')

这个模型正确吗? 我想已经保存了类别的数据库。我需要一个页面,用户可以在其中创建新的配置文件并从复选框列表中选择类别。我应该在同一页面中使用两种形式,一种用于个人资料,另一种用于选择类别还是一种形式?我想我需要一个 ModelMultipleChoiceField 作为类别。 我还需要一个视图,该视图显示已填充配置文件和类别的相同表单,用户可以在其中更改配置文件名称,以及添加或删除类别。

如果您需要更多信息,请告诉我,非常感谢。

ProfileCategory 模型在这里是不必要的。使用 ManyToMany 字段实现相同的结果:

class Category(models.Model):
    name = models.CharField(max_length=50, blank=False)

class Profile(models.Model):
    name = models.CharField(max_length=255, blank=False)
    user = models.ForeignKey(User, blank=True, null=True)
    categories = models.ManyToManyField(Category, blank=True)

现在您可以像任何其他模型一样使用单一表单编辑个人资料。您唯一应该记住的是调用 save_m2m() 以防您覆盖表单的 save() 方法。

app/forms.py

from django import forms
from app.models import Profile

class ProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        widgets = {
            'categories': forms.CheckboxSelectMultiple,
        }

app/views.py

从 django.views.generic.edit 导入 CreateView

from app.forms import ProfileForm
from app.models import Profile

class ProfileCreate(CreateView):
    form_class = ProfileForm
    model = Profile

templates/app/profile_form.html

<form action="" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Create" />
</form>

app/urls.py

from app.views import ProfileCreate

urlpatterns = patterns('',
    ...
    url(r'^profile/create/', ProfileCreate.as_view()),
)

要更新配置文件,请使用 UpdateView 和相同的 ProfileForm class 和模板。

编辑:如果您需要 ProfileCategory 模型中的其他字段,则可以使用 through argument of the ManyToManyField. To edit such models you have to use formsets. Read more about it here, here and here.

将其设置为中间模型