简体   繁体   中英

Django best practice. Forms

I have a question related to forms in django(i'm new on it) Look. Here i have form that looks like:

class ProccessAgentForm(forms.Form):
    agent_id = forms.HiddenInput()
    main_name = forms.IntegerField()
    company_name = forms.CharField(max_length=60)
    company_state = forms.CharField(max_length=60)
    company_city = forms.CharField(max_length=60)
    company_country = forms.CharField(max_length=60)
    company_post_code = forms.IntegerField()
    agent_first_name = forms.CharField(max_length=60)
    agent_last_name = forms.CharField(max_length=60)
    agent_phone = forms.CharField(max_length=60)
    agent_fax = forms.CharField(max_length=60)
    agent_email = forms.EmailField()
    agent_city = forms.CharField(max_length=60)
    agent_post_code = forms.IntegerField()
    agent_state = forms.CharField(max_length=60)
    agent_country = forms.CharField(max_length=60)
    signer_first_name = forms.CharField(max_length=60)
    signer_last_name = forms.CharField(max_length=60)
    signer_title = forms.CharField(max_length=60)

And i parsed it like(i know it's not the best choice):

form = ProccessAgentForm(request.POST)
    if form.is_valid():
        ....
    designated_company = DesignatedCompany()
    designated_company.pdf_link = copyright_agent.pdf_link
    designated_company.name = request.POST['company_name']
    designated_company.address = company_address
    designated_company.city = request.POST['company_city']
    designated_company.post_code = request.POST['company_post_code']
    designated_company.state = request.POST['company_state']
    designated_company.country = request.POST['company_country']
    designated_company.save()

    agent = DesignatedAgent()
    agent.company = designated_company
    agent.first_name = request.POST['agent_first_name']
    agent.last_name = request.POST['agent_last_name']
    agent.email = request.POST['agent_email']
    agent.address = agent_address
    agent.city = request.POST['agent_city']
    agent.country = request.POST['agent_country']
    agent.post_code = request.POST['agent_post_code']
    agent.state = request.POST['agent_state']
    agent.fax = request.POST['agent_fax']
    agent.phone = request.POST['agent_phone']
    agent.save()

and so on... How can i make it more readable? Should i split logic to forms ? I know about model Forms, but here i have foreign keys as you saw. I'd appreciate for more detailed response :)

How can i make it more readable?

First you can make it safer by using your form's cleaned_data instead of request.POST - it will contain cleaned up, sanitized, and eventually correctly typed values instead of the raw strings from the request's body.

A bit unrelated but while we're at it: a postal code (zip code) is NOT an integer, it's a string (eventually containing only numeric characters depending on the country).

Then you could use objects.create() and pass your data directly instead of creating a blank model instance, assigning all attributes manually and then saving it:

data = form.cleaned_data
designated_company = DesignatedCompany.objects.create(
    pdf_link=copyright_agent.pdf_link,
    name=data['company_name'],
    address=company_address,
    city=data['company_city'],
    # etc
    )

And finally : just use a pair of ModelForms instead.

Should i split logic to forms ?

The answer is in the question.

I know about model Forms, but here i have foreign keys as you saw.

And ? How is it a problem ? Exclude fields you don't want / can't use now from the ModelForm and use the commit=False flag when saving the second form so you can add the missing parts yourself.

You can even facade both forms and all this inner working in a "form-like" class of your own (a class that doesn't inherhit from Form but has the same API - at least the parts your interested in - and delegates to your CompanyForm and AgentForm) so the view's code don't have to bother...

You can use ModelForm to automatically generate forms that create model instances on save, like this:

class DesignatedCompanyForm(ModelForm):
     class Meta:
         model = DesignatedCompany
         fields = ['name', 'city', 'post_code', 'state', 'country']

There is also CreateView that doesn't require separate form:

class DesignatedCompanyCreate(CreateView):
    model = DesignatedCompany
    fields = ['name', 'city', 'post_code', 'state', 'country']

(snippets aren't tested, some fixes could be needed)

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