Question

I currently have a simple site, with very simple form submissions, but due to the organization im trying to implement, I already have a long, repetitive and ugly code. So basicly I have two views:

def base(request):

if request.method == "POST":
    if "seetag" in request.POST:
        seetagform = SeeTagForm(request.POST)
        if seetagform.is_valid():
            cd = seetagform.cleaned_data
            p = Tag.objects.get(name=cd["name"])
            return HttpResponseRedirect(reverse("main:see",args=(p.id,)))
        else:
            createform = CreateForm()
            return render(request,"tags/base.html",{"seetagform":seetagform,
                                                    "createform":createform})
    if "newevent" in request.POST:
        createform = CreateForm(request.POST)
        if createform.is_valid():
            cd = createform.cleaned_data
            print cd["day"]
            return HttpResponseRedirect(reverse("main:base"))
        else:
            seetagform = SeeTagForm()
            return render(request,"tags/base.html",{"seetagform":seetagform,
                                                    "createform":createform})   
else:
    seetagform = SeeTagForm()
    createform = CreateForm()                           
    return render(request,"tags/base.html",{"seetagform":seetagform,
                                            "createform":createform})

def see(request,tag_id):

if request.method == "POST":
    if "seetag" in request.POST:
        seetagform = SeeTagForm(request.POST)
        if seetagform.is_valid():
            cd = seetagform.cleaned_data
            p = Tag.objects.get(name=cd["name"])
            events = p.events.all()
            return HttpResponseRedirect(reverse("main:see",args=(p.id,)))
        else:
            createform = CreateForm()
            p = Tag.objects.get(pk=tag_id)
            events = p.events.all()
            return render(request,"tags/see.html",{"p":p,
                                                    "events":events,
                                                    "seetagform":seetagform,
                                                    "createform":createform})
    if "newevent" in request.POST:
        createform = CreateForm(request.POST)
        if createform.is_valid():
            cd = createform.cleaned_data
            print cd["day"]
            return HttpResponseRedirect(reverse("main:see",args=(tag_id,)))
        else:
            seetagform = SeeTagForm()
            return render(request,"tags/see.html",{"p":p,
                                                    "events":events,
                                                    "seetagform":seetagform,
                                                    "createform":createform})

else:
    seetagform = SeeTagForm()
    createform = CreateForm()
    p = Tag.objects.get(pk=tag_id)
    events = p.events.all()                             
    return render(request,"tags/see.html",{"p":p,
                                            "events":events,
                                            "seetagform":seetagform,
                                            "createform":createform})   

Where SeeTagForm is just a form.CharField and CreateForm is just a form.IntegerField. You can notice their almost identical. The two templates are these:

base.html:

<head>
<div class="back">
    <h1> Flux </h1>
    <hr>
</div>
</head>

<body>
<p>
    <form action="{% url 'main:base' %}" method="POST">
        {%for error in seetagform.name.errors %}
        <p> {{ error }} </p>
        {% endfor %}
        {% csrf_token %}
        <button class="btn" type="submit" name="seetag">See</button>
        {{ seetagform.name }}
    </form>
</p>


<p>
    <form action="{% url 'main:base' %}" method="POST">
        {%for error in createform.day.errors %}
        <p> {{ error }} </p>
        {% endfor %}
        {% csrf_token %}
        <button class="btn" type="submit" name="newevent">Create</button>
        {{ createform.day }}
    </form>
</p>

</body>         

see.html:

<head>
<div class="back">
    <h1> Flux </h1>
    <hr>
</div>
</head>

<body>
<p>
    <form action="{% url 'main:see' p.id%}" method="POST">
        {%for error in seetagform.name.errors %}
        <p> {{ error }} </p>
        {% endfor %}
        {% csrf_token %}
        <button class="btn" type="submit" name="seetag">See</button>
        {{ seetagform.name }}
    </form>
</p>

{% if events %}
    <ul>
        {% for ev in events %}
            <li> {{ ev.start|date:'H:i d/m/Y'}} </li>
        {% endfor %}
    </ul>
{% endif %} 

<p>
    <form action="{% url 'main:see' p.id%}" method="POST">
        {%for error in createform.day.errors %}
        <p> {{ error }} </p>
        {% endfor %}
        {% csrf_token %}
        <button class="btn" type="submit" name="newevent">Create</button>
        {{ createform.day }}
    </form>
</p>

</body>

What I'm trying to implement is the following. As you enter the website, it displays the base.html. Now, if you submit the seetagform validly, the objects inside the Tag with that name will be displayed using the see view (and template).

The reason why this is getting so messy, is because I want to keep the same html submission layout across all pages, but, as above, if i'm to display the objects, it will be using the see view. Clearly mess arises when I have to program all the possible outcomes of the form submissions in both views (in the base view, if an invalid form is submited, it says in the view and displays the error, without going to the see view; in the see view, if an invalid form is submited it will stay in the see view, display the error, but has to keep displaying what it was showing before the submission in the see template; you get the mess!)

Do you have any advices on how should I structure this? Basicly I want to have some part of the html to be always the same, but different views to be called according to input. Should I use jQuery to handle some sort of "generalized" form submissions?

Sorry for the long code and thanks in advance,

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top