Django m2m 表单保存”通过“桌子
我在保存包含“通过”类表的 m2m 数据时遇到问题。 我想将所有选定的成员(在表单中选择)保存在直通表中。 但我不知道如何初始化视图中的“通过”表。
我的代码:
class Classroom(models.Model):
user = models.ForeignKey(User, related_name = 'classroom_creator')
classname = models.CharField(max_length=140, unique = True)
date = models.DateTimeField(auto_now=True)
open_class = models.BooleanField(default=True)
members = models.ManyToManyField(User,related_name="list of invited members", through = 'Membership')
class Membership(models.Model):
accept = models.BooleanField(User)
date = models.DateTimeField(auto_now = True)
classroom = models.ForeignKey(Classroom, related_name = 'classroom_membership')
member = models.ForeignKey(User, related_name = 'user_membership')
并在视图中:
def save_classroom(request):
classroom_instance = Classroom()
if request.method == 'POST':
form = ClassroomForm(request.POST, request.FILES, user = request.user)
if form.is_valid():
new_obj = form.save(commit=False)
new_obj.user = request.user
new_obj.save()
membership = Membership(member = HERE SELECTED ITEMS FROM FORM,classroom=new_obj)
membership.save()
我应该如何初始化成员资格以便正确填充成员资格表?
I'm having trouble in saving a m2m data, containing a 'through' class table.
I want to save all selected members (selected in the form) in the through table.
But i don't know how to initialise the 'through' table in the view.
my code:
class Classroom(models.Model):
user = models.ForeignKey(User, related_name = 'classroom_creator')
classname = models.CharField(max_length=140, unique = True)
date = models.DateTimeField(auto_now=True)
open_class = models.BooleanField(default=True)
members = models.ManyToManyField(User,related_name="list of invited members", through = 'Membership')
class Membership(models.Model):
accept = models.BooleanField(User)
date = models.DateTimeField(auto_now = True)
classroom = models.ForeignKey(Classroom, related_name = 'classroom_membership')
member = models.ForeignKey(User, related_name = 'user_membership')
and in the view:
def save_classroom(request):
classroom_instance = Classroom()
if request.method == 'POST':
form = ClassroomForm(request.POST, request.FILES, user = request.user)
if form.is_valid():
new_obj = form.save(commit=False)
new_obj.user = request.user
new_obj.save()
membership = Membership(member = HERE SELECTED ITEMS FROM FORM,classroom=new_obj)
membership.save()
How should I initialise the membership for the Membership table to be populated right?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果使用正常的 m2m 关系(不通过中间表),您可以替换:
with
但如果使用中间表,您需要手动处理 POST 数据并创建包含所有必填字段的 Membership 对象 (类似问题)。最基本的解决方案是将您的视图更改为以下内容:
注意如何操作 request.POST (.getlist)。这是因为 post 和 get 是 QueryDict 对象,有一些影响(request.POST['members'] 将始终返回一个对象!)。
您可以修改此代码以使其更可靠(错误处理等),并且更详细,例如:
但请注意,您正在循环中执行一些数据库查询,这通常不是一个好主意(就性能而言)。
In case of using normal m2m relation (not through intermediary table) you could replace:
with
But in case of using intermediary tables you need to manually handle POST data and create Membership objects with all required fields (similar problem). The most basic solution is to change your view to something like:
Note how request.POST is manipulated (.getlist). This is because post and get are QueryDict objects which has some implications (request.POST['members'] will return always one object!).
You can modify this code to get it more reliable (error handling etc.), and more verbose, eg:
But note that you are performing some db queries in a loop which is not a good idea in general (in terms of performance).
就像 dzida 所做的那样,但使用 form.cleaned_data 而不是 request.post:
您还需要考虑一些成员资格可能会被删除,因此:
如果您使用模型表单(例如在通用 CBV 中:
form_class=ClassroomForm
),覆盖上面的保存逻辑并将其放入save
方法中,如下所示:Like what dzida did, but use form.cleaned_data instead of request.post:
You also need to consider some memberships might be deleted, so:
If you use model forms (like in a generic CBV:
form_class=ClassroomForm
), override and put the saving logic above in thesave
method, something like:您还需要为成员指定教室:
我想您还应该删除
accept = models.BooleanField(User)
中的User
。如果您使用auto_now
,则无需在保存时设置日期!但也许 `auto_now_add 更可能是您所需要的(http://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.DateField)You also need to specify the classroom for the membership:
I guess you should also remove
User
inaccept = models.BooleanField(User)
. It shouldn't be necessary to set the date upon saving if you are usingauto_now
! But maybe `auto_now_add is more likely what you need (http://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.DateField)这就是我在通用 UpdateForm 基于类的视图 (django 1.8) 中使用 form_valid 方法为类似但不同的应用程序执行此操作的方法。
This is how I did it in a generic UpdateForm class-based view (django 1.8) for a similar yet different application using the form_valid method.