简体   繁体   中英

Trying to hide button if next step does not exist

I am trying to make the button "next" disappear if there is no next step. I have tried the following and got stuck here. I have tasks with related steps using ForeignKey.

I think my method is not working because the PK is not always starting at 1. example task one have steps pk 1,2,3. Task two have steps pk 4,5,6.

Is it possible to make the PK always be 1,2,3 for each task? Then this might work? Or is there a better solution?

views.py

def step_detail(request, task_pk, step_pk):
    step = get_object_or_404(Step, task_id=task_pk, pk=step_pk)
    next_step_pk = step_pk + 1
    next_step = Step.objects.filter(pk=next_step_pk)
    if next_step.count() == 0:
        next_step_pk = None

    return render(request, 'dailytask/step_detail.html', {'step': step,
                                                          'next_step_pk': next_step_pk})

models.py:

class Task(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    user_completed = models.BooleanField(default=False)
    title = models.CharField(max_length=255)
    description = models.TextField(blank=True, default="")
    category = models.CharField(max_length=255, choices=CATEGORIES, default="traffic")
    done_message = models.TextField(null=True, default="")

    def __str__(self):
        return self.title


class Step(models.Model):
    title = models.CharField(max_length=255)
    description = models.TextField(blank=True, default="")
    user_completed = models.BooleanField(default=False)
    content = models.TextField(blank=True, default="")
    order = models.IntegerField(default=0)
    step_number = models.IntegerField(default=1)
    task = models.ForeignKey(Task, on_delete=models.CASCADE)

    class Meta:
        ordering = ['order', ]

    def __str__(self):
        return self.title

step_detail.html

I want this button to hide when there are no more steps in the task.

{% if next_step_pk %}
    <a href="{% url 'step' task_pk=step.task.pk step_pk=next_step_pk %}">
        <button class="btn btn-primary btn-block" type="button" style="background-color:rgba(0,123,255,0);margin-bottom:0px;">Next Step</button>
    </a>
{% endif %}

urls.py:

path('<int:task_pk>/<int:step_pk>/', views.step_detail, name='step'),

Indexing the PK to find the next step isn't going to work. The PK isn't related to the task.
Imagine that you have two tasks with 3 steps, then you add a new step to the first task. That would mean the first task would have 4 steps with pks of 1,2,3 and 7.

You have a relation between task and step. Set up a related name in the foreignkeyField.
task = models.ForeignKey(Task, on_delete=models.CASCADE, related_name="steps")
https://docs.djangoproject.com/en/2.1/ref/models/fields/

Then when doing the lookup you can do such:

next_steps = step.task.steps.filter(order__gt=step.order)
This will do a lookup in the database for all steps for that task, which have an order number greater than step.order. I might have the syntax wrong, but I think I got it correct, if it doens't work do some reading here:
https://docs.djangoproject.com/en/2.1/topics/db/queries/

Then you can call next_steps.count() and next_steps[0] to get the next step. Now that you have a working method to get the next step, you should be able to figure out a way to toggle the button.

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