Problem with pk that does not exist yet

1

I have the following urls:

# urls.py
url(r'^proposal/(?P<pk>\d+)/$', ProposalDetail.as_view(), name='proposal_detail'),
url(r'^contract/(?P<pk>\d+)/$', ContractDetail.as_view(), name='contract_detail'),
url(r'^proposal/edit/contract/$', 'create_contract', name='create_contract_url'),

It means that I have /proposal/1/ , but in my example I will not have /contract/3/ yet, that is, /contract/3/ is a contract that does not exist yet, and when it exists it will have a pk that can be different from proposal .

# views.py
class ProposalDetail(DetailView):
    template_name = 'core/proposal/proposal_detail.html'
    model = Proposal

For contract exists I will execute the following function ...

def create_contract(request, pk):
    if request.user.is_authenticated:
        proposal = Proposal.objects.get(pk=pk)
        if proposal.status != 'co':
            return HttpResponse('O status do orçamento deve ser concluido.')
        else:
            contractor = proposal.work.customer
            obj = Contract(
                proposal=proposal,
                contractor=contractor
            )
            obj.save()
            proposal.status = 'a'
            proposal.save()
    return redirect('/contract/%d' % obj.id)

... from this button.

# proposal_detail.html
<form class="navbar-form navbar-right" action="." method="get">
    <a class="btn btn-primary" href="{% url 'create_contract_url' proposal.id %}"><i class="icon-edit icon-white"></i> Criar Contrato</a>
</form>

The problem is that I can not control the pk correctly.

Question: How do I improve this code to inform pk of proposal in function create_contract and redirect the page to /contract/3 , where 3 will be a new pk of contract , but it does not exist yet?

    
asked by anonymous 26.10.2015 / 02:45

2 answers

-1

Resolved.

@login_required
def create_contract(request, proposal_id):
    if request.user.is_authenticated:
        proposal = Proposal.objects.get(pk=proposal_id)
        if proposal.status != 'co':
            return HttpResponse('O status do orçamento deve ser concluido.')
        else:
            contractor = proposal.work.customer
            contract = Contract(
                proposal=proposal,
                contractor=contractor
            )
            contract.save()
            proposal.status = 'a'
            proposal.save()
    return redirect('/contract/%d' % contract.id)
    
28.10.2015 / 02:47
1
Assuming Contract has a ForeignKey of Proposal, you can assign the value in the save act, for example:

#models
class Contract(models.Model):
    proposal = models.ForeignKey('Proposal', blank=True)

#views:
def create_contract(request, pk):
    proposal = Proposal.objects.get(pk=pk)
    form = ContractForm(request.POST or None)
    if request.METHOD == 'POST':
        if form.is_valid():
            obj = form.save(commit=False)
            obj.proposal = proposal
            obj.save()
            return redirect('/contract/%d' % obj.id)

    return render(request, "seu_template.html", {'form':form, 'proposal':proposal})

Remembering that it is not very suggestive you use the pk of the url for two things, in the template you passed the proposal id in url:

{% url 'create_contract_url' proposal.id %}"

And in the redirect of your view, you are returning the created contract id:

return redirect('/contract/%d' % obj.id)

It is interesting that you refer to one thing only in your url, in case you want the two pk's, pass the two pk's in the url.

If every contract refers to a proposal, it becomes more intuitive than your contract url is this way:

url(r'^(?P<proposal_id>\d+)/contract/new/$', ContractCreate.as_view(), name='contract_create'),
url(r'^(?P<proposal_id>\d+)/contract/(?P<pk>\d+)/$', ContractUpdate.as_view(), name='contract_edit'),
url(r'^(?P<proposal_id>\d+)/contract/(?P<pk>\d+)/$', ContractDetail.as_view(), name='contract_detail'),

Respecting the idea of CreateView, UpdateView and DetailView, the system will be much more readable.

link

    
26.10.2015 / 03:13