【问题标题】:Changing a Django model from ForeignKey to ManytoMany getting Invalid field name(s) given in select_related: 'group'. Choices are: user将 Django 模型从 ForeignKey 更改为 ManytoMany,在 select_related:'group' 中给出无效的字段名称。选择是:用户
【发布时间】:2018-12-05 03:49:58
【问题描述】:

我想更改我的帖子模型。之前我有一个非常简单的关系。有UserPostGroup三种型号。用户可以创建帖子,并且帖子必须属于 1 个组。 示例: 用户 Samir 在 Football 上写了一篇帖子。这篇文章属于体育组。下面是模型的外观

早期型号:

class Post(models.Model):
    user = models.ForeignKey(User, related_name='posts')
    group = models.ForeignKey(Group, related_name='posts')
    title = models.CharField(max_length=250, unique=True)
    slug = models.SlugField(allow_unicode=True, unique=True, max_length=500)
    message = models.TextField()   

我想更改此设置,使每个帖子最多可以属于 3 个组,最少可以属于 1 个组。

下面是我的模型

class Post(models.Model):
    user = models.ForeignKey(User, related_name='posts')
    group = models.ManyToManyField(Group, related_name='posts', max_length=3)
    title = models.CharField(max_length=250, unique=True)
    slug = models.SlugField(allow_unicode=True, unique=True, max_length=500)
    message = models.TextField()

帖子创建成功,但未重定向到帖子详细信息页面并出现以下错误。同样在 django 管理员中,帖子中的组是空白的。下面是我的DetailView

我的观点是:

from braces.views import SelectRelatedMixin

class PostDetail(SelectRelatedMixin, DetailView):
    model = Post
    select_related = ('user', 'group')

    def get_queryset(self):
        queryset = super().get_queryset()
        return queryset.filter(user__username__iexact=self.kwargs.get('username'))

    def get_context_data(self, **kwargs):
        context = super(PostDetail, self).get_context_data()            
        return context

我的 DetailView 网址是:

url(r'^(?P<username>[-\w]+)/(?P<slug>[-\w]+)/$', views.PostDetail.as_view(), name='single'),

以下是错误

我尝试将select_related 更改为prefetch_related,但问题仍然存在。我该如何解决这个问题

**********以下基于@Ruddra的解决方案*****

很抱歉,我相信这几乎解决了。更改相关选择后,出现以下错误

我相信这可能与我的群组网址有关,下面是我的群组modelviewurl,非常简单

型号

class Group(models.Model):
    name = models.CharField(max_length=250, unique=True)
    description = models.TextField(default='', blank=True)
    members = models.ManyToManyField(User, through='GroupMember')

视图是 1 行

class GroupCreate(LoginRequiredMixin, CreateView):
    model = Group
    fields = ('name', 'description')


class GroupList(ListView):
    model = Group


class GroupDetail(DetailView):
    model = Group

最后 Url

url(r'^posts/in/(?P<slug>[-\w]+)/$', views.GroupDetail.as_view(), name='single'),

你认为我做错了什么

【问题讨论】:

  • 更改关系后,你的命令makemigrationsmigrate运行成功了吗?
  • 是的。他们成功运行
  • 你能重新检查真实的数据库,有没有任何新表有 group_id 和 post_id ?该表将保留多对多的真实数据。您可以发布您的命令文件makemigrations 吗?
  • 仅供参考,max_lengthManyToManyField 没有影响
  • 可能用prefetch_related='posts' 更改为PrefethRelatedMixin。因为你定义了related_name='posts'

标签: django python-3.x django-models django-views django-urls


【解决方案1】:

根据documentation

返回一个“遵循”外键关系的查询集, 在执行查询时选择其他相关对象数据。 这是一个性能提升器,它导致单个更复杂 查询,但意味着以后使用 foreign-key 关系不会 需要数据库查询。

意味着select_related 仅适用于OneToOneForignKey 关系。

在这里,您使用的是SelectRelatedMixin,它有select_related。在该字段中有 groupuser。这可能是导致问题的原因。而是像这样使用PrefethRelatedMixin

class PostDetail(PrefetchRelatedMixin, DetailView):
    model = Post
    prefetch_related = ('user', 'group')

【讨论】:

  • 我知道我把它改成了prefetch_related,但它仍然报错
  • 在您的代码中,我可以看到您使用的是SelectRelatedMixin,它有select_related。这里有 groupuser。这可能会导致问题
  • 那么您是否建议我删除SelectRelatedMixin 并将select_related 更改为prefetch_related
  • 我建议你使用PrefethRelatedMixin
  • @SamirTendulkar 请查看我的更新答案。希望有帮助
猜你喜欢
  • 2016-08-30
  • 2016-06-30
  • 2017-04-19
  • 2020-01-12
  • 1970-01-01
  • 2016-03-06
  • 2021-04-20
  • 1970-01-01
  • 2014-02-06
相关资源
最近更新 更多