从两个或更多表中显示相关数据在一个DetailView中

huangapple go评论58阅读模式
英文:

Displaying related data from two or more tables in a DetailView

问题

Here's the translation of the code-related part of your message:

我找不到关于在视图调用中如何传递所有命名参数 **kwargs 到覆盖的 "get_context_data" 方法的信息。

有三个模型:

class User(models.Model):
    email = models.CharField(unique=True)
    company_id = models.IntegerField(blank=True, null=True)
    first_name = models.CharField(blank=True, null=True)
    last_name = models.CharField(blank=True, null=True)
class Company(models.Model):
    logo = models.CharField(blank=True, null=True)
    name = models.CharField(blank=True, null=True)
    full_name = models.CharField(blank=True, null=True)
    address = models.CharField(blank=True, null=True)
    phone = models.CharField(blank=True, null=True)
    email = models.CharField(blank=True, null=True)
    kpp = models.CharField(blank=True, null=True)
    okved = models.CharField(blank=True, null=True)
    bik = models.CharField(blank=True, null=True)   
class Order(models.Model):
    user_id = models.IntegerField(blank=True, null=True)
    amount_total_cents = models.BigIntegerField()
    amount_mean_cents = models.BigIntegerField()
    created_at = models.DateTimeField()

模型之间的关联:

Company-User 1对多,User-Order 1对多

在视图中直接输出数据而不覆盖 "get_context_data" 方法时,没有问题。但是,在覆盖该方法并通过主键链接两个表时,就会出现问题:

1.
company/urls.py

urlpatterns = [
    path('company/<int:pk>', CompanyShow.as_view(), name='company_show')
]

company/views.py

class CompanyShow(DetailView):
    model = Company
    template_name = 'company/company_show.html'
    context_object_name = 'company'

    def get_context_data(self, **kwargs):
        context = super(CompanyShow, self).get_context_data(**kwargs)
        context['users'] = User.objects.filter(company_id=self.kwargs['pk'])
        return context

company_show.html

    <p>ID: {{ company.id }}</p>
    <p>Name: {{ company.name }}</p>
    <p>Members:
    {% for user in users %}
        <li>
        <a href="{% url 'user:user_show' user.id %}">{{ user }}</a>
        </li>
    {% endfor %}
    </p>

2.
user/urls.py

urlpatterns = [
    path('user/<int:pk>', UserShow.as_view(), name='user_show')
]

user/views.py

class UserShow(DetailView):
    model = User
    template_name = 'user/user_show.html'
    context_object_name = 'user'

user_show.html

    <p>ID: {{ user.id}}</p>
    <p>Name: {{ user.first_name }}</p>
    <p>Surname: {{ user.last_name }}</p>
    {% if user.company_id %}
        <a href="{% url 'company:company_show' user.company_id %}">
            Company profile (id {{ user.company_id }})
        </a>
    {% else %}
        No company
    {% endif %}

问题如下:

从 **kwargs 中应传递什么匹配参数到 order/views.py,以便根据 "user" 表中的 "id" 在 "order" 表的 "user_id" 字段中过滤所需对象的列表?并且根据结果,需要在 .html 中显示公司 - 如何连接 "users" 表和 "company" 表?

但是,当绑定发生在订单中时会出现困难:

order/urls.py

urlpatterns = [
    path('order/<int:pk>', OrderShow.as_view(), name='order_show')
]

order/views.py

class OrderShow(DetailView):
    model = Order
    template_name = 'order/order_show.html'
    context_object_name = 'order'

    def get_context_data(self, **kwargs):
        context = super(OrderShow, self).get_context_data(**kwargs)
        context['users'] = User.objects.filter(id=self.kwargs['user_id'])  
        return context

order_show.html

    <p> Member:
    {% for user in users %}
        <li>
        <a href="{% url 'user:user_show' user.id %}">{{ user }}</a>
        </li>
    {% endfor %}
    </p>

在描述的实现中,出现了错误:

异常类型 KeyError
异常值 'user_id'
英文:

I did not find information on how all named arguments **kwargs are passed in the overridden "get_context_data" method in the view call.

There are 3 models:

class User(models.Model):
    email = models.CharField(unique=True)
    company_id = models.IntegerField(blank=True, null=True)
    first_name = models.CharField(blank=True, null=True)
    last_name = models.CharField(blank=True, null=True)
class Company(models.Model):
    logo = models.CharField(blank=True, null=True)
    name = models.CharField(blank=True, null=True)
    full_name = models.CharField(blank=True, null=True)
    address = models.CharField(blank=True, null=True)
    phone = models.CharField(blank=True, null=True)
    email = models.CharField(blank=True, null=True)
    kpp = models.CharField(blank=True, null=True)
    okved = models.CharField(blank=True, null=True)
    bik = models.CharField(blank=True, null=True)   
class Order(models.Model):
    user_id = models.IntegerField(blank=True, null=True)
    amount_total_cents = models.BigIntegerField()
    amount_mean_cents = models.BigIntegerField()
    created_at = models.DateTimeField()

Communication between models:

Company-User 1 to M, User-Order 1 to M

There are no problems with direct output of data in the view without overriding the "get_context_data" method. However, there are no problems when overriding the method and linking two tables through the primary key:

1.
company/urls.py

urlpatterns = [
    path(&#39;company/&lt;int:pk&gt;&#39;, CompanyShow.as_view(), name=&#39;company_show&#39;)
]

company/views.py

class CompanyShow(DetailView):
    model = Company
    template_name = &#39;company/company_show.html&#39;
    context_object_name = &#39;company&#39;

    def get_context_data(self, **kwargs):
        context = super(CompanyShow, self).get_context_data(**kwargs)
        context[&#39;users&#39;] = User.objects.filter(company_id = self.kwargs[&#39;pk&#39;])
        return context

company_show.html

    &lt;p&gt;ID: {{ company.id }}&lt;/p&gt;
    &lt;p&gt;Name: {{ company.name }}&lt;/p&gt;
    &lt;p&gt;Members:
    {% for user in users %}
        &lt;li&gt;
        &lt;a href=&quot;{% url &#39;user:user_show&#39; user.id %}&quot;&gt;{{ user }}&lt;/a&gt;
        &lt;/li&gt;
    {% endfor %}
    &lt;/p&gt;

2.
user/urls.py

urlpatterns = [
    path(&#39;user/&lt;int:pk&gt;&#39;, UserShow.as_view(), name=&#39;user_show&#39;)
]

user/views.py

class UserShow(DetailView):
    model = User
    template_name = &#39;user/user_show.html&#39;
    context_object_name = &#39;user&#39;

user_show.html

    &lt;p&gt;ID: {{ user.id}}&lt;/p&gt;
    &lt;p&gt;Name: {{ user.first_name }}&lt;/p&gt;
    &lt;p&gt;Surname: {{ user.last_name }}&lt;/p&gt;
    {% if user.company_id %}
        &lt;a href=&quot;{% url &#39;company:company_show&#39; user.company_id %}&quot;&gt;
            Company profile (id {{ user.company_id }})
        &lt;/a&gt;
    {% else %}
        No company
    {% endif %}

The question is the following:

What matching parameter should be passed from **kwargs to order/views.py so that the list of required objects is filtered according to the "user" table "id" in the "order" table of the "user_id" field? And according to the result, it is required to display the company in .html - how to connect the table of "users" and the "company" next?

However, the difficulty is when the binding goes in orders:

order/urls.py

urlpatterns = [
    path(&#39;order/&lt;int:pk&gt;&#39;, OrderShow.as_view(), name=&#39;order_show&#39;)
]

order/views.py

class OrderShow(DetailView):
    model = Order
    template_name = &#39;order/order_show.html&#39;
    context_object_name = &#39;order&#39;

    def get_context_data(self, **kwargs):
        context = super(OrderShow, self).get_context_data(**kwargs)
        context[&#39;users&#39;] = User.objects.filter(id = self.kwargs[&#39;user_id&#39;])  
        return context

order_show.html

    &lt;p&gt; Member:
    {% for user in users %}
        &lt;li&gt;
        &lt;a href=&quot;{% url &#39;user:user_show&#39; user.id %}&quot;&gt;{{ user }}&lt;/a&gt;
        &lt;/li&gt;
    {% endfor %}
    &lt;/p&gt;

In the described implementation, the error:

Exception Type:     KeyError
Exception Value:    &#39;user_id&#39;

答案1

得分: 0

以下是您要翻译的内容:

It turns out to be a simple solution, if not attached to **kwargs: ```context['users'] = User.objects.filter(id = self.object.user_id)```

Final view:

class OrderShow(DetailView):
    model = Order
    template_name = 'order/order_show.html'
    context_object_name = 'order'
    
    def get_context_data(self, **kwargs):
        context = super(OrderShow, self).get_context_data(**kwargs)   
        context['users'] = User.objects.filter(id = self.object.user_id)  
        return context

And with 3 tables, where two do not have a direct relationship:

class OrderShow(DetailView):
    model = Order
    template_name = 'order/order_show.html'
    context_object_name = 'order'
    
    def get_context_data(self, **kwargs):
        context = super(OrderShow, self).get_context_data(**kwargs)   
        context['users'] = User.objects.filter(id = self.object.user_id)        
        for user in context['users']:
            context['companies'] = Company.objects.filter(id=user.company_id)
        return context
英文:

It turns out to be a simple solution, if not attached to **kwargs: context[&#39;users&#39;] = User.objects.filter(id = self.object.user_id)

Final view:

class OrderShow(DetailView):
    model = Order
    template_name = &#39;order/order_show.html&#39;
    context_object_name = &#39;order&#39;
    
    def get_context_data(self, **kwargs):
        context = super(OrderShow, self).get_context_data(**kwargs)   
        context[&#39;users&#39;] = User.objects.filter(id = self.object.user_id)  
        return context

And with 3 tables, where two do not have a direct relationship:

class OrderShow(DetailView):
    model = Order
    template_name = &#39;order/order_show.html&#39;
    context_object_name = &#39;order&#39;
    
    def get_context_data(self, **kwargs):
        context = super(OrderShow, self).get_context_data(**kwargs)   
        context[&#39;users&#39;] = User.objects.filter(id = self.object.user_id)        
        for user in context[&#39;users&#39;]:
            context[&#39;companies&#39;] = Company.objects.filter(id=user.company_id)
        return context

huangapple
  • 本文由 发表于 2023年5月10日 20:31:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76218457.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定