Django 表单:仅显示登录用户的 manytomany 对象
Django Form: Only show manytomany objects from logged in user
当前的问题是我的表单显示登录用户曾经创建的所有投资组合。该表单应仅显示登录用户创建的投资组合。
像这样:
associated_portfolios manytomany field = ...objects.filter(user=user_id)
我不确定这是否应该在 forms.py 或 views.py 中实施,如果是,如何实施。我一直在浏览 django 文档并找到 'formfield_for_manytomany' 但不确定这是否仅适用于管理员。
Models.py
class Portfolio(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=20)
description = models.CharField(max_length=250, blank=True, null=True)
class Post(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=50)
body = RichTextUploadingField(blank=True, null=True)
associated_portfolios = models.ManyToManyField(Portfolio, blank=True)
created_on = models.DateField(auto_now_add=True, editable=False)
Views.py
class PostCreate(CreateView):
model = Post
form_class = PostCreateForm
def formfield_for_manytomany(self, db_field, request, **kwargs):
self.fields['associated_portfolios'] = Portfolio.objects.filter(user=self.request.user)
return super().formfield_for_manytomany(db_field, request, using=self.using, **kwargs)
forms.py
class PortfolioCreateForm(ModelForm):
class Meta:
model = Portfolio
fields = ['user', 'name', 'description']
class PostCreateForm(ModelForm):
class Meta:
model = Post
fields = ['user', 'title', 'body', 'category', 'associated_portfolios']
你试过这个吗
self.fields['associated_portfolios'] = Post.objects.filter(associated_portfolios__portfolio__user=request.user)
或
user_posts = Post.objects.filter(user=request.user)
self.fields['associated_portfolios'] = user_posts.associated_portfolios.all()
详细了解 M2M 关系查询 here,因为我认为您的问题可能与此有关。
此外,我不确定你的实际数据,也许它是正确的,并且它给出了正确的结果,因为针对当前用户过滤 Portfolio
模型以使其对象看起来适合我,但无论如何仔细检查所有内容再次.
最后要注意的是,将 related_name
添加到您的模型字段中,这样您就可以轻松地将其用于反向关系,而不是使用 Django 的默认命名方式,这样会更清晰并提供更好的理解。
由于您使用的是 ModelForm
,因此 associated_protfolios
字段将是 ModelMultipleChoiceField
[docs]. This field has a queryset
attribute [docs]。我们要修改那个属性。
Django 的 CreateView
有一个方法 get_form
,在本例中它将获取您的 PostCreateForm
。这是过滤字段查询集的好地方,因为我们可以访问用户:
class PostCreate(CreateView):
model = Post
form_class = PostCreateForm
def get_form(self, *args, **kwargs):
form = super().get_form(*args, **kwargs) # Get the form as usual
user = self.request.user
form.fileds['associated_portfolios'].queryset = Portfolio.objects.filter(user=user)
return form
当前的问题是我的表单显示登录用户曾经创建的所有投资组合。该表单应仅显示登录用户创建的投资组合。
像这样:
associated_portfolios manytomany field = ...objects.filter(user=user_id)
我不确定这是否应该在 forms.py 或 views.py 中实施,如果是,如何实施。我一直在浏览 django 文档并找到 'formfield_for_manytomany' 但不确定这是否仅适用于管理员。
Models.py
class Portfolio(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=20)
description = models.CharField(max_length=250, blank=True, null=True)
class Post(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=50)
body = RichTextUploadingField(blank=True, null=True)
associated_portfolios = models.ManyToManyField(Portfolio, blank=True)
created_on = models.DateField(auto_now_add=True, editable=False)
Views.py
class PostCreate(CreateView):
model = Post
form_class = PostCreateForm
def formfield_for_manytomany(self, db_field, request, **kwargs):
self.fields['associated_portfolios'] = Portfolio.objects.filter(user=self.request.user)
return super().formfield_for_manytomany(db_field, request, using=self.using, **kwargs)
forms.py
class PortfolioCreateForm(ModelForm):
class Meta:
model = Portfolio
fields = ['user', 'name', 'description']
class PostCreateForm(ModelForm):
class Meta:
model = Post
fields = ['user', 'title', 'body', 'category', 'associated_portfolios']
你试过这个吗
self.fields['associated_portfolios'] = Post.objects.filter(associated_portfolios__portfolio__user=request.user)
或
user_posts = Post.objects.filter(user=request.user)
self.fields['associated_portfolios'] = user_posts.associated_portfolios.all()
详细了解 M2M 关系查询 here,因为我认为您的问题可能与此有关。
此外,我不确定你的实际数据,也许它是正确的,并且它给出了正确的结果,因为针对当前用户过滤 Portfolio
模型以使其对象看起来适合我,但无论如何仔细检查所有内容再次.
最后要注意的是,将 related_name
添加到您的模型字段中,这样您就可以轻松地将其用于反向关系,而不是使用 Django 的默认命名方式,这样会更清晰并提供更好的理解。
由于您使用的是 ModelForm
,因此 associated_protfolios
字段将是 ModelMultipleChoiceField
[docs]. This field has a queryset
attribute [docs]。我们要修改那个属性。
Django 的 CreateView
有一个方法 get_form
,在本例中它将获取您的 PostCreateForm
。这是过滤字段查询集的好地方,因为我们可以访问用户:
class PostCreate(CreateView):
model = Post
form_class = PostCreateForm
def get_form(self, *args, **kwargs):
form = super().get_form(*args, **kwargs) # Get the form as usual
user = self.request.user
form.fileds['associated_portfolios'].queryset = Portfolio.objects.filter(user=user)
return form