简体   繁体   中英

Django - limit the choices of a choice field in a form

I'm having a problem with a choice field in Django. I need to have a form to add order movements to a work orders.

These are the choices in choices.py

STATUS_CHOICES = (
    (1, ("Orden Creada")),
    (2, ("En Tienda Asociada")),
    (3, ("Recibida en Cuyotek")),
    (4, ("En Mesa de Trabajo")),
    (5, ("Trabajo completado")),
    (6, ("Sin Solución")),
    (7, ("Lista para retirar en Cuyotek")),
    (8, ("Lista para retirar en Tienda Asociada")),
    (9, ("Es necesario contactar al cliente")),
    (10, ("En espera de Repuestos")),
    (20, ("ENTREGADA")),
)

And I need to limit the choices to show only "8 and 20" if the user is not staff.

This is the model in models.py

class OrderMovements(models.Model):
    fk_workorder = models.ForeignKey(WorkOrder)
    status = models.IntegerField(choices=STATUS_CHOICES, default=1)
    timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)

    def __str__(self):
        return str(self.fk_workorder)

And this the form in forms.py

class AddMovementForm(forms.ModelForm):

    class Meta:
        model = OrderMovements
        fields = ['status']

    def clean_status(self):
        status = self.cleaned_data.get('status')
        return status

I can't find info about how to make this filter.

Thanks for your help!

You need to define an __init__() method in your form class which takes is_staff as an argument. is_staff can be a boolean value.

def __init__(self, *args, **kwargs):
    is_staff = kwargs.pop('is_staff')
    super(AddMovementForm, self).__init__(*args, **kwargs)
    if is_staff:
        self.fields['status'].choices = STAFF_STATUS_CHOICES
    else:
        self.fields['status'].choices = STATUS_CHOICES

When you initialize your form, you can do

AddMovementForm(is_staff=True)  # or
AddMovementForm(is_staff=False)

In your __init__() method of your form, you can change the choices of status field.

class AddMovementForm(forms.ModelForm):
    class Meta:
        model = OrderMovements
        fields = ['status']

    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user', None)
        super(AddMovementForm, self).__init__(*args, **kwargs)
        if not self.user.is_staff:
            limited_choices = [(choice[0], choice[1]) for choice in STATUS_CHOICES if choice[0] == 8 or choice[0] == 20]
            self.fields['status'] = forms.ChoiceField(choices=limited_choices)])

    def clean_status(self):
        status = self.cleaned_data.get('status')
        return status

You have to pass the request.user to your form as well. Notice that this is a rough idea, nothing tested, but you should get the idea.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM