Search code examples
djangodjango-forms

How to pass a Django form response through another template


I am creating a site for users to record their chicken's weights and I am trying to design a confirmation form for if a user tries to submit another weight for the same chicken on the same day. In other words, if a record already exists for that date, how to ask the user if it should be overwritten without the user re-entering the weight. This is all I have so far:

# views.py
def add_record(request, chicken) -> HttpResponseRedirect | HttpResponsePermanentRedirect | HttpResponse:
    """
    View for the "record_weight.html" 
    Post & Get methods
    """
    if request.method == "POST":
        form = RecordForm(request.POST)
        if form.is_valid():
            record = form.save(commit=False)
            record.chicken = Chicken.objects.filter(number=chicken).first()
            record.date = datetime.now().date()
            try:
                Record.save(record)
            except ValidationError:
                # There is a record for that day, render another form asking if they want to overwrite
                return render(request, "tags/duplicate_record.html", {"bird": record.chicken}) 
            return redirect("/admin/tags/record/") 

    form = RecordForm()
    try:
        birds = Chicken.objects.all()

        req_bird = birds.filter(number=chicken).first()
    except Chicken.DoesNotExist:
        raise Http404("Bird does not exist")
    try:
        req_records = Record.objects.filter(chicken_id=chicken).order_by("date").reverse()
    except Record.DoesNotExist:
        req_records = []
    return render(request, "tags/record_weight.html", {"bird": req_bird, "records": req_records, "form": form, "nav_filter": get_birds_navbar(birds)})
# duplicate_records.html (styling removed for easier reading)

{% extends "tags/layout.html" %}

{% block content %}
<div>
    <div>
        <h2>There is already a weight for today!</h2>
        <p>Do you want to overwrite that entry</p>
        <form>
            <a href="/records/{{ bird.number }}">No</a>
            <button>Overwrite</button>
        </form>
    </div>
</div>
{% endblock %}

I frankly cannot find any way to implement this functionality. Thanks in advance!


Solution

  • If you want to do that without redirecting to another view, you can use form errors to check with user if they need data to be overwritten, and different names of template buttons to confirm the choice. This is simplified view (without validations etc.):

    def add_record(request):
        context = {}
        if request.method == 'POST':
            form = RecordForm(request.POST)
            overwrite = True if 'do_overwrite' in request.POST else False
            keep = True if 'keep' in request.POST else False
            date = form.data['date']
            if Record.objects.filter(date=date):
                if overwrite:
                    # Overwrite the record as you see fit
                    pass
                elif keep:
                    # Redirect to somewhere else
                    pass
                else:
                    form.add_error('date', 'Do you want to overwrite that entry?')
                    context['ask_overwrite'] = True
            else:
                # Save the record
                pass
        else:
            form = RecordForm()
        context['form'] = form    
        
        return render(request, 'tags/record_weight.html', context=context)
    

    And this is template with different buttons:

    <form method="post">
        {% csrf_token %}
        {{form.date}}
        {% if form.date.errors %}
        <ul>
            {% for error in form.date.errors %}
                <li>{{ error }}</li>
            {% endfor %}
        </ul>
        {% endif %}
        {% if ask_overwrite %}
            <button type="submit" name="do_overwrite">Overwrite</button>
            <button type="submit" name="keep">No</button>
        {% else %}
            <button type="submit">Submit</button>
        {% endif %}
    </form>