简体   繁体   中英

Django: Validate GET parameter

I offer discount codes in my checkout. I created form where users can type in the discount code and click on apply. The form checks if the discount code is valid and then applies it.

Now I want to add the functionality to add to the url domain.com/event/?discount=ABC

I want to check if request.GET is set an then somehow redirect it to the 'form' / transform it into a request.POST , so I can validate it. I am currently struggling to find the right approach to do that. Do you have any suggestions on how I could use the GET-parameter and validate it the same way as I would use the form?

views.py

def dispatch(self, request, *args, **kwargs):
    # Provide discount_code to all functions
    self.discount_code = None

    # Check if discount code is saved as a session
    self.discount_code_session = request.session.get(
        request.event.discount_code_cookie(), None)
    if self.discount_code_session:
        self.discount_code = Discount.objects.filter(
            code=self.discount_code_session,
            event=self.request.event.pk
        ).first()

@transaction.atomic
def post(self, request, *args, **kwargs):

    # Discount Code
    if self.discount_form.is_valid():
        discount_code = self.discount_form.cleaned_data['code']
        request.session[request.event.discount_code_cookie()] = discount_code
        return redirect('events:detail', request.organizer.slug, request.event.slug)

forms.py

class DiscountFormEventPage(forms.ModelForm):
    # Remove required attribute from HTML elements
    use_required_attribute = False
    class Meta:
        model = Discount
        fields = (
            'code',
        )
    def __init__(self, *args, **kwargs):
        self.event = kwargs.pop('event')
        super().__init__(*args, **kwargs)
        for visible_field in self.visible_fields():
            visible_field.field.widget.attrs['class'] = 'form-control'
    def clean_code(self):
        input_code = self.cleaned_data['code']
        # Check if discount code exists
        discount_code = self.event.discounts.filter(code=input_code).first()
        if not discount_code:
            raise forms.ValidationError(_("The discount code couldn't be found."),
                                        code='code_exists')
        elif not discount_code.is_active():
                raise forms.ValidationError(_("This discount code is not available\
                                               anymore."),
                                            code='code_not_active')
        return input_code

UPDATE:

I now added this here in my view.py (DetailView):

def get(self, request, *args, **kwargs):

    discount_code_get = request.GET.get('code')
    if discount_code_get:
        return DiscountFormEventPage(
            prefix='discount',
            data=request.GET,
            event=self.request.event,
        )

I don't see where you're getting the parameter, is it what your question is about? You can get it as follow:

# request.GET is a dict-like object
code = request.GET['discount']
# safer alternative against KeyError
code = request.GET.get('discount')
# if discount may be specified multiple times
code = request.GET.getlist('discount')

If you want to use a form to validate the incoming data, you should be able to pass it as first argument:

form = DiscountFormEventPage(request.GET)
if form.is_valid():
     data = form.cleaned_data
     return redirect('events:detail', request.organizer.slug, request.event.slug)

I could solve it now with this code. Thank you to Bruno for helping me to find the right track:

def get(self, request, *args, **kwargs):
    # Apply discount via GET parameter ?code=DISCOUNT
    discount_code_get = request.GET.get('code')
    if discount_code_get:
        self.discount_form = DiscountFormEventPage(
            data=request.GET,
            event=self.request.event,
        )
    if self.discount_form.is_valid():
        discount_code = self.discount_form.cleaned_data['code']
        request.session[request.event.discount_code_cookie()] = discount_code
        return redirect('events:detail', request.organizer.slug, request.event.slug)
    return super().get(request, *args, **kwargs)

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