英文:
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('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 %}
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('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>
In the described implementation, the error:
Exception Type: KeyError
Exception Value: 'user_id'
答案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['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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论