gpt4 book ai didi

python-2.7 - 是否有可能同时具有一对多和多对多关系的模型?

转载 作者:行者123 更新时间:2023-12-03 17:20:33 28 4
gpt4 key购买 nike

我有一个系统,我将拥有可由一名或多名教师教授的产品(类(class))。这些讲师还可以创建产品,在这种情况下,他们应该可以通过作为其开发人员的产品进行访问。但是,我还希望能够访问所有可用于该产品的讲师。

我不确定如何设置 SQLAlchemy 模型,以便我可以为 Product.developer 建立一对多关系。但是 Product.instructors 的多对多关系.

模型.py

from app import db

instructors = db.Table('instructors',
db.Column('instructor_id', db.Integer, db.ForeignKey('instructor.id')),
db.Column('product_id', db.Integer, db.ForeignKey('product.id'))
)


class Instructor(db.Model):
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(64))
#courses qualified for etc

class Product(db.Model):
id = db.Column(db.Integer, primary_key = True)
courseName = db.Column(db.String(64))
developer = db.relationship('Instructor', secondary=instructors,
backref=db.backref('developed', lazy='dynamic'))
instructors = db.relationship('Instructor', secondary=instructors,
backref=db.backref('products', lazy='dynamic'))

def __repr__(self):
return '<Category> %r>' % (self.courseName)

View .py
from flask import render_template, flash, redirect
from app import app, models

@app.route('/product/<courseName>')
def show_product(courseName):
product = models.Product.query.filter_by(courseName=courseName).first_or_404()
return render_template('show-product.html', product=product)

模板:show-product.html
<!-- extend base layout -->
{% extends "base.html" %}

{% block content %}
<br><b>Course Name:</b> {{product.courseName}}
<br><b>Curriculum developer:</b>
{% for developer in product.developer %}
{{developer.name}}
{% endfor %}
<br><b>Lead Instructor:</b>
<br><b>Certified Instructors:</b>
{% for instructor in product.instructors %}
{{instructor.name}}&nbsp;
{% endfor %}


{% endblock %}`enter code here`

这是我正在运行以在数据库中输入值的代码。
#!flask/bin/python
from app import db, models

instruct1 = models.Instructor(name="instructor1")
db.session.add(instruct1)
db.session.commit()

instruct2 = models.Instructor(name="instructor2")
db.session.add(instruct2)
db.session.commit()

dev = models.Instructor(name="developer")
db.session.add(dev)
db.session.commit()

prod = models.Product(courseName = "test")

prod.instructors = [instruct1]
prod.instructors.append(instruct2)

prod.developer = [dev]

print "Instructors:"
for instructor in prod.instructors:
print instructor.name

print "Developer"
for i in prod.developer:
print i.name

db.session.add(prod)
db.session.commit()

这是输出:
Instructors:
instructor1
instructor2
Developer
developer

但是当我查看网页时,我看到:
Course Name: test 
Curriculum developer: instructor1 instructor2 developer
Lead Instructor:
Certified Instructors: instructor1 instructor2 developer

更新:谢谢doobeh!我更新了我的代码, http://bpaste.net/show/o8PtsY3Kvu8bxKnDEo24/但是当我运行python代码时,我收到错误“在关系'Product.instructors'上创建反向引用'产品'时出错:映射器'Mapper|Instructor|instructor'上存在该名称的属性”

最佳答案

如果您正确创建开发人员关系,听起来您的问题将会消失。目前,您已经从您正在使用的多对多关系中复制了这种关系。因此,您的开发人员被添加到与讲师相同的堆栈中 - 您没有立即看到它的原因是因为您直到再次打印出列表之后才将其提交到数据库。一旦您将这些列表提交到数据库并重新查询,您将获得您在模板中看到的倍数。

我想如果你改变你的Product模型为:

class Product(db.Model):
id = db.Column(db.Integer, primary_key = True)
courseName = db.Column(db.String(64))

developer_id = db.Column(db.Integer, db.ForeignKey='instructor.id'))
developer = db.relationship('Instructor', backref='develops')

instructors = db.relationship('Instructor', secondary=instructors,
backref=db.backref('products', lazy='dynamic'))

def __repr__(self):
return '<Category> %r>' % (self.courseName)

它会按您的预期工作(未经测试的代码!)。由于您在每个 Product 上仅存储一个开发人员现在,您不需要遍历这些值,或者在添加它们时传入列表/附加。

为了更清楚地说明为什么不能有多个多对多连接
使用相同的字段,让我们分解 SQL 级别上发生的事情。

您的 M2M 连接表 instructors有两个字段, instructor_idproduct_id .然后,您创建三个讲师:
id:1    instructor1
id:2 instructor2
id:3 developer

然后你创建一个产品:
id:1    product

如果我将前两位讲师添加到该产品中, instructors链接表将存储如下信息:
product_id      instructor_id
1 1
1 2

然后将开发人员添加到同一个表中:
product_id      instructor_id
1 1
1 2
1 3

所以当你说“给我这个产品的所有导师”时,SQLAlchemy 是
会问模特,“嘿,我在这里有一个关系,显示产品
链接到 instructors 中的讲师 table ,所以给我所有的教练
产品 ID 为 1"的产品,当然你会得到三个结果,而不仅仅是你期望的两个结果,当你询问开发人员时,你会得到相同的三个结果,因为它使用相同的链接。

如果您想创建两个多对多连接,您只需要创建第二个名为 developers 的链接表。或类似的,其中仅包含与该关系相关的信息。但是,在这种情况下,因为您只需要一个开发人员链接到一个产品,您可以只使用一个简单的 ForeignKey映射该关系。

关于python-2.7 - 是否有可能同时具有一对多和多对多关系的模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14884485/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com