Django ManyToMany的关联问题

67 views
Skip to first unread message

jimmy xiong

unread,
Nov 2, 2010, 9:35:14 PM11/2/10
to pyth...@googlegroups.com
各位好!

我在用Django写一个网站的时候遇到了多对多数据库关联上的问题,自己尝试了两天,查了很多资料也没有解决,请各位高人帮忙指教。

 20 class SpecialCategory(models.Model):
 21     name = models.CharField(max_length=50, verbose_name=u'定制名称', unique=True)
 22     slug = models.CharField(verbose_name=u'短地址', unique=True, max_length=50)
 23     dname = models.CharField(max_length=50, verbose_name=u'显示名称', unique=True)

 
 41 class Article(models.Model):
 42     name = models.CharField(max_length=50, verbose_name=u'标题')
 43     slug = models.CharField(verbose_name=u'短地址', unique=True, max_length=50)
 44     meta = models.CharField(max_length=50, verbose_name=u'标签')
 45     info = models.TextField(max_length=500, verbose_name=u'简述')
 46     pub_date = models.DateTimeField(verbose_name=u'发行时间')
 47     pub_switch = models.BooleanField(verbose_name=u'出版')
 48     image = models.ImageField(upload_to = UPLOAD_IMAGE, verbose_name=u'上传图片', blank=True, null=Tru    e)
 49     content = models.TextField(verbose_name=u'正文')
 50     category = models.ManyToManyField(Category, verbose_name=u'所属分类')
 51     comments = models.ManyToManyField(Comments, verbose_name=u'评论',blank=True, null=True)
 52     special_category = models.ManyToManyField(SpecialCategory, verbose_name=u'特殊定制', blank=True, n    ull=True)
 53     comments_switch = models.BooleanField(verbose_name=u'评论开关')
 54
 55     def __unicode__(self):
 56         return self.name
 57
 58     def save(self):
 59         meta_words = self.meta.split(",")
 60         for i in meta_words:
 61             #p = SpecialCategory(id=None, name=i, slug=i, dname=i)
 62             if SpecialCategory.objects.filter(slug = i):
 63                 self.special_category=[SpecialCategory.objects.get(slug = i)]
 64             else:
 65                 a=self.special_category.create(name=i, slug=i, dname=i)
 66                 self.special_category=(a,)
 67         super(Article, self).save()

我想做一个自动添加tags分类的东东,先读取meta中的值,用逗号分隔开,然后插入到special_category
问题出现在我用红色标记的地方,我尝试还过使用add方式添加关联。
代码均没有报错的通过,但是数据库之间的关系就是没有关联上。----即:后台管理页面多对多选择框中相对应的选项没有被选中。


金浩

unread,
Nov 2, 2010, 9:46:14 PM11/2/10
to pyth...@googlegroups.com
在save代码开头加
if not self.id:
    super(Article, self).save()

看看


--
来自: python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表)
发言: pyth...@googlegroups.com
退订: python-cn+...@googlegroups.com (向此发空信即退!)
详情: http://groups-beta.google.com/group/python-cn
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp

jimmy xiong

unread,
Nov 2, 2010, 9:54:01 PM11/2/10
to pyth...@googlegroups.com
谢谢,
按照你的方式试过了,还是老样子。

金浩

unread,
Nov 2, 2010, 9:59:34 PM11/2/10
to pyth...@googlegroups.com

报什么错

jimmy xiong

unread,
Nov 2, 2010, 10:02:17 PM11/2/10
to pyth...@googlegroups.com
不报错。

jimmy xiong

unread,
Nov 3, 2010, 2:13:50 AM11/3/10
to pyth...@googlegroups.com
有人关联成功过吗?请教一下方法。
在后台管理页面多对多选择框中自己手动关联的话是可以成功的。

超孙

unread,
Nov 3, 2010, 2:22:52 AM11/3/10
to pyth...@googlegroups.com
把67行挪到save函数开头呢

jimmy xiong

unread,
Nov 3, 2010, 2:30:28 AM11/3/10
to pyth...@googlegroups.com
挪到开头也是一样的。数据库会正常插入输入。但是add()似乎不会执行,或者执行了之后没有效果。也不报错什么的。

超孙 <xlsun...@gmail.com> 於 2010年11月3日下午2:22 寫道:
把67行挪到save函数开头呢

超孙

unread,
Nov 3, 2010, 2:37:31 AM11/3/10
to pyth...@googlegroups.com
多对多这么保存
self(当前对象).special_category.add(要保存的对象)

jimmy xiong

unread,
Nov 3, 2010, 2:39:47 AM11/3/10
to pyth...@googlegroups.com
试过,文中忘记说明了,没用,状况一样。
谢谢

超孙 <xlsun...@gmail.com> 於 2010年11月3日下午2:37 寫道:
多对多这么保存
self(当前对象).special_category.add(要保存的对象)

jimmy xiong

unread,
Nov 3, 2010, 2:43:38 AM11/3/10
to pyth...@googlegroups.com
如果你也正好在研究Django,不妨也用add方法写一个关联试试。
如果可以通过的话麻烦共享一下。
感激不尽

超孙

unread,
Nov 3, 2010, 2:57:38 AM11/3/10
to pyth...@googlegroups.com
class Author(models.Model):
    name = models.CharField(max_length = 20)
    age = models.CharField(max_length = 20)


class Book(models.Model):
    author = models.ManyToManyField(Author)
   
   

Views:
    at=Author()
    at.name ='test'
    at.age = '12'
    at.save()
   
    book = Book()
    book.author.add(at)

这样应该是好使的

@@

unread,
Nov 3, 2010, 2:59:01 AM11/3/10
to pyth...@googlegroups.com
不知道为何没关联上。
但就算是关联上了肯定也是错的,代码是每次都给赋值而不是添加

def save(self):
super(Article, self).save()
for i self.meta.split(","):
p, created = SpecialCategory.objects.get_or_create(name=i, slug=i, dname=i)
self.special_category.add(p)
#super(Article, self).save() 如果不行的话save两次试试

2010/11/3 jimmy xiong <jimmy.py...@gmail.com>:

超孙

unread,
Nov 3, 2010, 3:02:00 AM11/3/10
to pyth...@googlegroups.com
class Author(models.Model):
    name = models.CharField(max_length = 20)
    age = models.CharField(max_length = 20)


class Book(models.Model):
    bookname = models.CharField(max_length = 20)

    author = models.ManyToManyField(Author)
   
   

Views:
    at=Author()
    at.name ='test'
    at.age = '12'
    at.save()
   
    book = Book()
    book.bookname = 'xxx'
    book.save()
    book.author.add(at)

超孙

unread,
Nov 3, 2010, 3:03:41 AM11/3/10
to pyth...@googlegroups.com
我就是这么弄的 代码不一定对 带意思是对的
你可以在shell里面 把两个模型导入 测试

jimmy xiong

unread,
Nov 3, 2010, 4:06:50 AM11/3/10
to pyth...@googlegroups.com
感谢大家提供的方法。
@@ 的get_or_create方法挺方便
孙超的add()所说的add方法我也有试过的

问题依旧没有解决,数据可以正常插入到SpecialCategory,但数据依旧没能关联上Author中。

jimmy xiong

unread,
Nov 3, 2010, 4:17:34 AM11/3/10
to pyth...@googlegroups.com
我把实验包发上来,用户名和密码都是123
Dj.rar

jimmy xiong

unread,
Nov 3, 2010, 4:30:26 AM11/3/10
to pyth...@googlegroups.com
数据是正常插入了的,所以用all()可以得到数据。

jimmy xiong <jimmy.py...@gmail.com> 於 2010年11月3日下午4:17 寫道:
我把实验包发上来,用户名和密码都是123

@@

unread,
Nov 3, 2010, 4:36:32 AM11/3/10
to pyth...@googlegroups.com
我看了下没有问题啊
save 方法是这样的
def save(self):
super(Article, self).save()
meta_words = self.name.split(",")
for i in meta_words:
p, created = SpecialCategory.objects.get_or_create(name=i)
self.specialcategory.add(p)

去掉了最后一个save

In [15]: a = models.Article(name='aaa,bbb,ccc')

In [16]: a
Out[16]: <Article: aaa,bbb,ccc>

In [17]: a.save()

In [18]: models.SpecialCategory.objects.all()
Out[18]: [<SpecialCategory: aaa>, <SpecialCategory: bbb>,
<SpecialCategory: ccc>]

In [19]: models.Article.objects.all()
Out[19]: [<Article: aaa,bbb,ccc>]

In [20]: a.specialcategory
Out[20]: <django.db.models.fields.related.ManyRelatedManager object at 0x00DB66B
0>

In [21]: a.specialcategory.all()
Out[21]: [<SpecialCategory: aaa>, <SpecialCategory: bbb>,
<SpecialCategory: ccc>]

a.specialcategory 已经有值了。没有问题

2010/11/3 jimmy xiong <jimmy.py...@gmail.com>:


> 数据是正常插入了的,所以用all()可以得到数据。
>
> jimmy xiong <jimmy.py...@gmail.com> 於 2010年11月3日下午4:17 寫道:
>>
>> 我把实验包发上来,用户名和密码都是123
>

金浩

unread,
Nov 3, 2010, 4:43:42 AM11/3/10
to pyth...@googlegroups.com
可能和你在admin里添加有关,你的save方法保存的数据被admin里面的保存覆盖掉了。

jimmy xiong

unread,
Nov 3, 2010, 4:51:42 AM11/3/10
to pyth...@googlegroups.com
多谢
经测试发现,在admin页面中添加的话会失败。
直接命令行输入可以。
是不是Django存储顺序的问题?

jimmy xiong

unread,
Nov 3, 2010, 4:53:10 AM11/3/10
to pyth...@googlegroups.com
恩恩,就是这个问题了。
我勒个叉呀。

嘿嘿,这个只不是要修改Django?

金浩

unread,
Nov 3, 2010, 4:58:29 AM11/3/10
to pyth...@googlegroups.com
如果你确定不会通过表单选择那些manaytomany field 只会通过save方法修改,可以再admin配置里加
exclude = ('specialcategory', )
试试

jimmy xiong

unread,
Nov 3, 2010, 5:08:05 AM11/3/10
to pyth...@googlegroups.com
好滴,谢谢。

感谢大家的帮助,菜鸟受教了。

Ps:有没有两全之法呀?

金浩

unread,
Nov 3, 2010, 5:10:47 AM11/3/10
to pyth...@googlegroups.com
肯定有,看admin的源码重载一些方法或Form应该可以达到目的
Reply all
Reply to author
Forward
0 new messages