How to make a queryset inside a queryset?

2019-08-19 01:39发布

问题:

I wan't to make a parent-child app in django. So, let me explain how i want this to work. I got a view where all humans are shown (parents and children). I click on any of them, so it opens a different view, where all of the children and parents are shown. I can click at any of them and see the same thing for everyone.

It only worked (kinda) this way:

class Parent(models.Model):
      ...(name, etc.)
class Child(models.Model):
      ...(same fields)
      field = ForeignKey(Human, on_delete='CASCADE') #something like this

But Child is not the same class as Parent, so i can't see same thing for child objects. If i inherit it like this:

class Parent(...):
      ...
class Child(Parent):
      field = ForeignKey(Human, on_delete='CASCADE') #Tried different types of fields

it wouldn't work. First, it says that i should add default value for parent_prt (or something like that) when i'm trying to make migrations. Then, if i add default values for fields he asks me to and make a migration, it wouldn't let me save it in db. So i wonder if there is a way to, for example, make a queryset of parents inside every element of parents queryset?

Parent.objects.parent_set.add(some parent obj created and saved before)#doesn't work, but i want something like this

Or what would you advise?

回答1:

I would write a comment instead, but I don't have enough reputation to do so (I'm new here). Besides that, I need some clarity on what you want done.

Now I think I understand what you mean. It sounds like you want to be able to show related objects from the Parent class in your template (Child), but I'm not sure because it seems like one of your views shows all parents and children. Then you click on any of them, and then you want it to show ALL of the same people again??? It would help a lot if you showed the whole view, url patterns, and your full models for clarity. Either way, you can find the documentation for that here, though I'll show it with my own example because theirs isn't laid out well. It uses the related-model_set syntax in your template.

So throughout this, I will assume you want what I said in bold/italics. But up front, if my assumption is wrong, to point out some possible errors in your code: In your Child model you have a ForeignKey to Human, not Parent... Do you have another model named Human?? Or did you intend to make each Child related to a Parent, or what??? You also haven't done python manage.py makemigrations and python manage.py migrate because you said you got the errors.

Now here's my answer on how to do what I said in bold/italics up top.

If you wanted each child to be related to a parent, your models would look like this:

class Parent(models.Model):
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)

class Child(models.Model):
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    # If the parent is deleted, all kids will be deleted too... Not realistic in real life, but I assume you'll apply this principle elsewhere, such as a Blog with Comments related to it.
    parent = models.ForeignKey(Parent, on_delete=models.CASCADE)

And then to show children in your template, your view would look like this, assuming you added children and parents from the admin panel:

def all_parents_and_kids(request):
    # to get related objects (Child), all you need to do is get the model they're related to (Parent)
    all_parents = Parent.objects.all()
    return render(request, 'all_people.html', {'all_parents': all_parents})

Your template would look like this, but you would need some css to make it look prettier than this example:

{% for parent in all_parents %}
    <section style="border: 2px blue dashed;">
        <h1>{{ parent.first_name }} {{ parent.last_name }}</h1>
        <h2>Children of this parent:</h2>
        <ul>
            {% for child in all_parents.child_set %}
                <li>{{ child.first_name }} {{ child.last_name }}</li>
            {% endfor %}
        </ul>
    </section>
{% endfor %}

Is this what you wanted???

If yes, please give me a + so I can hopefully add comments at some point. If not, please clarify what you wanted.