我正在努力保存相同的表格两个表 - 有一个m2m的关系.我没有成功,我的错误仍然存在于以下内容:无法在指定中间模型的ManyToManyField上设置值.使用会员经理而不是会员资格是我的'直通表'.
我的代码:
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 = request.user,classroom=new_obj)
membership.save()
form.save_m2m()
return HttpResponseRedirect('.')
else:
form = ClassroomForm(user = request.user)
return render_to_response('classroom/classroom_form.html', {
'form': form,
},
context_instance=RequestContext(request))
Run Code Online (Sandbox Code Playgroud)
我的模特:
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 = …Run Code Online (Sandbox Code Playgroud) 我有 2 张桌子:餐厅和食物,第三张桌子 restaurant_foods 存储两张桌子之间的多对多关系
restaurants_foods = db.Table('restaurants_foods',
db.Column('restaurant_id', db.Integer, db.ForeignKey('restaurants.id'), primary_key=True),
db.Column('food_id', db.Integer, db.ForeignKey('foods.id'), primary_key=True),
db.Column('food_price', db.Float)
)
class Food(Model):
__tablename__ = "foods"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(255), nullable=False)
description = db.Column(db.String(255), nullable=True)
class Restaurant(Model):
__tablename__ = "restaurants"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(255), nullable=False)
foods = db.relationship('Food', secondary=restaurants_foods)
Run Code Online (Sandbox Code Playgroud)
现在,当我查询 Restautant.query.get(1).foods 时,我希望它包含 restaurant_foods 关联表中的 food_price 列
我是Django的新手,没有找到关于这个问题的任何参考.当我在django模型(models.py)中使用多对多字段时,我收到此错误.我想问题是从窗体(forms.py)中查看视图(views.py)中的m2m.如何在视图中分配m2m字段.
Django版本2.O python 3.5
models.py
class User(AbstractUser):
username=models.CharField(max_length=20)
email = models.EmailField(_('email address'), unique=True)
class Setupuser(models.Model):
organization=models.CharField(max_length=200,blank=False,null=True)
emails_for_help = models.ManyToManyField(User)
Run Code Online (Sandbox Code Playgroud)
views.py
class Set_user(FormView):
template_name="pkm_templates/set_up_user.html"
form_class = Set_User_Form
success_url = '/thanks/'
def form_valid(self, form):
org = form.cleaned_data.get('organization')
emails = form.cleaned_data.get("emails_for_help")
instance = Setupuser(organization=org,emails_for_help=emails)
instance.save()
return redirect("/")
Run Code Online (Sandbox Code Playgroud)
forms.py
class Set_User_Form(ModelForm):
emails_for_help =
forms.ModelMultipleChoiceField(queryset=User.objects.all(),
widget=forms.CheckboxSelectMultiple)
class Meta:
model=Setupuser
fields=["organization","emails_for_help"]
Run Code Online (Sandbox Code Playgroud) 我在保存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')
Run Code Online (Sandbox Code Playgroud)
并在视图中:
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 …Run Code Online (Sandbox Code Playgroud) 当我保存相关模型时,我正试图让多个模型更新.这应该是可以使用m2m_changed信号(它可以工作!但不在管理员?)例如
# i want the references field to update when related model is saved.
# so just call count_references
class Tag(models.Model):
"""Group everything into categories"""
# stuff stuff stuff
references = models.IntegerField(default=0, editable=False)
def count_references(self):
# just add up references each time to save headaches
self.references = 0
# search for reverse managers
sets = re.compile('^\w+_set$')
for rel_set in [method for method in dir(self) if sets.match(method)]:
self.references += getattr(self, rel_set).count()
self.save()
class Entry(models.Model):
"""Blog entry"""
# stuff stuff …Run Code Online (Sandbox Code Playgroud) 我最近开始在我的Django项目中使用信号(v.1.3)并且它们都工作正常,除了我无法弄清楚为什么m2m_changed信号永远不会在我的模型上被触发.通过在django管理表单上添加/删除PageChild内联实例来编辑Section实例.
我试图按照文档中的描述注册回调函数,但是没有得到任何结果.
摘自我的models.py
from django.db import models
from django.db.models.signals import m2m_changed
class Section(models.Model):
name = models.CharField(unique = True, max_length = 100)
pages = models.ManyToManyField(Page, through = 'PageChild')
class PageChild(models.Model):
section = models.ForeignKey(Section)
page = models.ForeignKey(Page, limit_choices_to = Q(is_template = False, is_background = False))
@receiver(m2m_changed, sender = Section.pages.through)
def m2m(sender, **kwargs):
print "m2m changed!"
m2m_changed.connect(m2m, sender = Section.pages.through, dispatch_uid = 'foo', weak = False)
Run Code Online (Sandbox Code Playgroud)
我错过了一些明显的东西吗
我遇到了一个奇怪的问题,我希望这里的某些人能够对此有所了解.
我正在重写模型的save()方法,以便在运行super()之后向ManyToMany字段添加一些值.我的问题是,当我在Django admin中保存时,值似乎被添加到关系中,但然后再次为空.
但是,如果我这样做,manage.py shell它没有问题.
我已经在那里放了两个打印语句,无论我是通过Django admin还是通过shell运行它,它们都会产生完全相同的输出.
class Store(models.Model):
holidays = models.ManyToManyField(StoreHoliday, blank=True)
copy_holidays_from = models.ForeignKey('Store', blank=True, null=True)
def save(self):
print '==== BEFORE SAVE:', self.holidays.all()
super(Store, self).save()
self.copy_holidays()
print '==== AFTER SAVE:', self.holidays.all()
def copy_holidays(self):
if self.pk and self.copy_holidays_from:
self.holidays.clear()
for h in self.copy_holidays_from.holidays.all():
self.holidays.add( h )
Run Code Online (Sandbox Code Playgroud)
这是print声明的输出:
==== BEFORE SAVE: []
==== AFTER SAVE: [<StoreHoliday: 10 Mar 2010, Chuck Norris birthday (Closed)>]
Run Code Online (Sandbox Code Playgroud)
有没有人对可能导致这种情况的原因有任何建议?
编辑:当通过管理界面保存时,Django似乎丢弃了save()中m2m关系的所有手动更改.这与处理表单的方式有关吗?
我在Django中使用以下模型模式(使用Postgres).
class A(Models.model):
related = models.ManyToManyField("self", null=True)
Run Code Online (Sandbox Code Playgroud)
给定A的QuerySet,我想返回一个字典A,将QuerySet中的每个实例尽可能快地映射到id其related实例的列表.
我可以肯定地遍历每个A并查询相关字段,但是有更优化的方法吗?
Django中的多对多关系示例:
class First(models.Model):
seconds = models.ManyToManyField(Second, through='Middle')
class Middle(models.Model):
first = models.ForeignKey(First)
second = models.ForeignKey(Second)
class Second(models.Model):
Run Code Online (Sandbox Code Playgroud)
根据中间模型的文档,只有一个相关对的ManytoManyField模型包含上面示例中的模型First.它是否正确?
如果是这样,哪个模型应包含该ManytoManyField字段?使用任何一方的关系是否有任何差异取决于它在哪里ManytoManyField?
谢谢
编辑(我应该更清楚):
我对中介表感兴趣,因为我将有额外的数据存储在关系中.
当我说使用时,我并不是指定义模型,我的意思是使用关系(否则我会让Django做它的事情).
如果我想要所有与第一个相关的秒,它是否与获得与第二个相关的所有第一个完全相同,或者ManytoManyField通过引入任何额外的功能使一个方向比另一个方向更容易?
我对Django的信号不是很熟悉,可以使用一些帮助.
如何在保存实例之前修改pk_set?我是否必须向信号呼叫者返回一些东西(比如kwargs)?或者我保存instance自己?
作为一个简单的例子:我希望确保在pk=1保存时我的所有视频都包含类别.我该怎么做m2m_changed?
class Video(models.Model):
category = models.ManyToManyField('Category')
def video_category_changed(sender, **kwargs):
action = kwargs.pop('action', None)
pk_set = kwargs.pop('pk_set', None)
instance = kwargs.pop('instance', None)
if action == "pre_add":
if 1 not in pk_set:
pk_set.update( [ 1 ] ) # adding this to the set
# do something else?
# profit?
m2m_changed.connect( video_category_changed, sender=Video.category.through )
Run Code Online (Sandbox Code Playgroud) m2m ×10
django ×9
python ×5
django-orm ×4
forms ×2
database ×1
django-admin ×1
flask ×1
many-to-many ×1
postgresql ×1
relationship ×1
signals ×1
sqlalchemy ×1