Теоретически, вы можете переопределить FormField, который генерирует django . В этом случае вы могли бы использовать Выбор виджета для поля post_type
.
Однако я думаю, что с вашим моделированием можно улучшить / нормализовать, и если это будет сделано, ваша проблемаразрешу. Рассмотрим следующие модели:
class Tier(models.Model):
name = models.CharField(max_length=128, blank=True)
value = models.IntegerField()
slug = models.SlugField(unique=True, blank=True)
class CustomUser(...):
tiers = models.ManyToManyField(Tier, related_name='users')
...
class Post(models.Model):
author = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
tier = models.ForeignKeyField(Tier)
title = models.CharField(max_length=200, null=True)
text = models.TextField()
url = models.URLField(max_length = 200, blank=True)
slug = models.SlugField(unique=True, blank=True)
Таким образом, вы, разные пользователи, можете иметь один и тот же уровень (что, вероятно, то, что вам нужно?) Без дублирования значений имени и уровня.
Теперь,когда вы создаете ModelForm
с Post, он автоматически предоставит вам поле выбора для всех существующих уровней. Однако вы просто хотите иметь возможность выбирать уровни, в которых находится пользователь, поэтому для этого поля вы должны установить пользовательский queryset
:
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')
Редактировать:Я только сейчас увидел, что вы хотите разрешить все уровни, в которых находится пользователь или которые имеют меньшее значение. Вы можете сделать это таким же образом, вам просто нужно адаптировать набор запросов:
max_tier_value = user.tiers.aggregate(Max('value')).value__max
self.fields['tier'].queryset = Tier.objects.filter(value__lte=max_tier_value)
Однако вы, вероятно, захотите сделать один из этих двух, но не оба:
- Каждый пользователь назначается с уровнем уровня и может создавать сообщения с любым уровнем более низкого уровня.
- Каждый пользователь назначается с несколькими уровнями уровня и может создавать сообщения только с этими уровнями.
Так, если вы идете с этим набором запросов, вы должны переделать так, чтобы CustomUser.tier
был models.ForeignKey(Tier, related_name='users')