I'd say you're missing a service layer.

It's known as a good practice to not have "business rules" in your views.

IP lookup should be done in your view anyway, because it's a "web
related thing". The `save_the_lead()` and email sending should be in
the service layer.

Extending a little bit and talking about pythonic code,
`IPInfo.get_result()` should not exist. Simply use the `result`
attribute or convert it to a read only property. Or, if this class
came to life just because the `get_result()` method, convert it to a
simple function.




On 21 October 2016 at 09:11, Andrew Chiw <[email protected]> wrote:
> In my views, I have this:
> def questionnaire(request):
>     def save_the_lead(cleaned_data, ipinfo):
>         email = cleaned_data.pop('email', None)
>         lead, created = Lead.objects.update_or_create(email=email)
>         lead.q = cleaned_data
>         lead.ipinfo = ipinfo
>         lead.save()
>         return lead
>
>     form = LeadForm(request.POST or request.GET or None)
>     """
>     Why am I still checking for request.method == "POST"?
>     if POST (valid data) to questionnaire, process it.
>     if GET (valid data) to questionnaire, display it first. Even if it's all
> valid.
>     """
>     if request.method == "POST":
>         if form.is_valid():
>             i = IPInfo(get_ip(request), dummy=True)
>             lead = save_the_lead(form.cleaned_data, i.get_result())
>             m = Matcher()
>             m.match([lead])
>             e = Emailer(lead)
>             e.send()
>             return redirect('results', lead.id)
>
>     return render(request, 'wizard/questionnaire.html', {'form': form})
>
> And IPInfo looks like this:
> import requests
> import ipdb
>
>
> class IPInfo:
>     def __init__(self, ip, dummy=False):
>         self.result = dict()
>         if (ip and not dummy):
>             response = requests.get('http://ipinfo.io/' + ip)
>             self.result = response.json()
>         elif (ip and dummy):
>             self.result = {"ip": ip}
>
>     def get_result(self):
>         return self.result
>
>
> The part I'm worried about is the IPInfo lookup class and how it is used in
> the view. I know you can mock classes in tests, but maybe I should use
> dependency injection instead? or is that not needed in Python?
> If I'm missing dependency injection: I don't have control over the code that
> runs before the view, so I cannot tell it to inject another instance of
> IPInfo in there.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at https://groups.google.com/group/django-users.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/2777f9b7-ec87-4dc5-ac8f-de971860c83b%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/CAFmXjSDVUwCE6Tpaiv_HMRvejkrA6XvSu0zWP0tjfSsUsctHZg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to