Как ограничить выбор CheckboxSelectMultiple для платного членства в Django

Я борюсь с моим кодом в Django. Мое приложение - сад, когда вы создаете новый сад и являетесь членом "плюс" членства, вы можете выбрать неограниченное количество растений. Но если вы являетесь членом бесплатного членства, вы можете выбрать только 3 растения. Как я могу это сделать? models.py

class Garden(models.Model):
    name = models.CharField(max_length=256)
    description = models.TextField(blank=True, default='')
    address = models.CharField(max_length=512)
    plant = models.ManyToManyField(Plant, related_name="gardens", through="GardenPlant")
    user = models.ForeignKey(User, null=True, on_delete=models.CASCADE)

class Membership(models.Model):
    PLUS = 'PL'
    FREE = 'FR'
    MEMBERSHIP_CHOICES = (
        (PLUS, 'plus'),
        (FREE, 'free')
    )
    slug = models.SlugField(null=True, blank=True)
    membership_type = models.CharField(choices=MEMBERSHIP_CHOICES, default=FREE, max_length=30)
    price = models.DecimalField(default=0, max_digits=999, decimal_places=2)


class UserMembership(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='user_membership', on_delete=models.CASCADE)
    membership = models.ForeignKey(Membership, related_name='user_membership', on_delete=models.SET_NULL, null=True)


class Subscription(models.Model):
    user_membership = models.ForeignKey(UserMembership, related_name='subscription', on_delete=models.CASCADE)
    active = models.BooleanField(default=True)

    def __str__(self):
      return self.user_membership.user.username

forms.py

class GardenForm(forms.ModelForm):
    class Meta:
        model = Garden
        fields = ['name', 'description', 'address', 'plant']


    def clean_plant(self):
        value = self.cleaned_data['plant']
        if len(value) > 3:
            raise forms.ValidationError("You can't select more than 3 items.")
        return value

    plant = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Plant.objects.all())

    def save(self, user):
        garden = super().save(commit=False)
        garden.user = user
        garden.save()
        garden.plant.add(*self.cleaned_data.get('plant'))

views.py

def create_garden(request):
    form = GardenForm(request.POST or None)
    if form.is_valid():
        form.save(request.user)

        return redirect('/garden')
    context = {"form": form,
               "has_subscription": subscription_check(request.user)}
    return render(request, "create_garden.html", context)

class MembershipView(ListView):
    model = Membership
    template_name = 'membership.html'

    def get_user_membership(self):
        user_membership_qs = UserMembership.objects.filter(user=self.request.user)
        if user_membership_qs.exists():
            return user_membership_qs.first()
        return None

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(**kwargs)
        current_membership = self.get_user_membership()
        context['current_membership'] = str(current_membership.membership)
        return context

    def post(self, request):
        current_membership = self.get_user_membership()
        current_membership.membership = Membership.objects.get(membership_type=request.POST.get('membership_type'))
        current_membership.save()
        return redirect('membership')

html код:

{% extends 'base.html' %}
{% block page_title %}Create garden{% endblock page_title %}
{% block body %}

<h1>Create garden</h1><br>
    <form action="{{ action_url }}" method="post">
        {% csrf_token %}
        Name: {{ form.name }}
        <br><br>
        Description: {{ form.description }}
        <br><br>
        Location: {{ form.address }}
        <br><br>
        Select your plants: {{ form.plant }}

        <br><br>


        {% if has_subscription %}Congratulate{% endif %}
        <input type="submit" value="Save">
    </form>

{% endblock body %}

что вы думаете? Я пытался поместить ValidationError в forms.py, как вы видите в моем коде, но это не работает.

Вернуться на верх