Django:将模型选择字段选项设置为queryset值和其他值

Django:将模型选择字段选项设置为queryset值和其他值,django,django-models,django-forms,Django,Django Models,Django Forms,在下面的Django模型中 class Post(models.Model): author = models.ForeignKey(CustomUser, on_delete=models.CASCADE,) title = models.CharField(max_length=200, null=True) text = models.TextField() post_url = models.URLField(max_length = 200, blank

在下面的Django模型中

class Post(models.Model):
    author = models.ForeignKey(CustomUser, on_delete=models.CASCADE,)
    title = models.CharField(max_length=200, null=True)
    text = models.TextField()
    post_url = models.URLField(max_length = 200, blank=True)
    post_type = models.IntegerField()
    slug = models.SlugField(unique=True, blank=True)

class Tiers(models.Model):
    user = models.ForeignKey(CustomUser, default=None, null=True, on_delete=models.CASCADE,)
    tier_name = models.CharField(max_length=128, blank=True) 
    tier_value = models.IntegerField() 
    slug = models.SlugField(unique=True, blank=True)
我想为下面这样的表单使用post模型

class PostForm(forms.ModelForm):
    class Meta:
        model = models.Post
        fields = ('title', 'text', 'post_url', 'post_type')
但是对于post\u type字段,我希望显示为下拉列表,其中包含来自层模型层值的选项。例如,如果user1在tier模型中有3个条目,tier_值为10、20和30。我想显示4个选项0、10、20和30。谁能帮我实现这个目标吗?

理论上,你可以。在这种情况下,您可以在
post\u type
字段中使用

然而,我认为通过您的建模可以改进/规范化,如果这样做,您的问题将得到解决。考虑这些模型:

类层(models.Model):
name=models.CharField(最大长度=128,空白=True)
value=models.IntegerField()
slug=models.SlugField(unique=True,blank=True)
类CustomUser(…):
层=模型.ManyToManyField(层,相关的\u name='users')
...
班级职务(models.Model):
author=models.ForeignKey(CustomUser,on_delete=models.CASCADE)
tier=型号。ForeignKeyField(tier)
title=models.CharField(最大长度=200,null=True)
text=models.TextField()
url=models.URLField(最大长度=200,空白=True)
slug=models.SlugField(unique=True,blank=True)
这样,不同的用户可以拥有相同的层(这可能是您想要的?),而不会重复名称和级别值

现在,当您使用Post创建
ModelForm
时,它将自动为您提供所有现有层的选择字段。但是,您只希望能够选择用户所在的层,因此可以为该字段设置自定义:

class PostForm(forms.ModelForm):
    def __init__(self, user, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['tier'].queryset = Tier.objects.filter(users__in=[user])

    class Meta:
        model = models.Post
        fields = ('title', 'text', 'url', 'tier')

编辑:我刚才看到您希望允许用户所在的所有层或价值较小的层。您也可以用同样的方法完成此操作,只需调整queryset:

max\u tier\u value=user.tiers.aggregate(max('value')).value\u max
self.fields['tier'].queryset=tier.objects.filter(value\u lte=max\u tier\u value)
但是,您可能希望执行以下两种操作之一,但不能同时执行这两种操作:

  • 每个用户都被分配了一个级别,并且可以创建具有任何较低级别的帖子
  • 每个用户都被分配了多个级别,并且只能创建具有这些级别的帖子

因此,如果你使用这个查询集,你应该重新建模,以便
CustomUser.tier
是一个
models.ForeignKey(tier,related_name='users')

我的第一个想法是为每个用户创建一个tier值为0的tier,这样我就可以分配给帖子了。我认为可能会有更好的解决办法,但我会同意这一点。谢谢