Python:如何在我的 Django 模板中传递外键的值?

Posted

技术标签:

【中文标题】Python:如何在我的 Django 模板中传递外键的值?【英文标题】:Python : How to pass the value of a foreign key in my Django template? 【发布时间】:2016-11-22 16:15:38 【问题描述】:

我创建了一个投标模型,以便类型 2 用户可以对类型 1 用户创建的某些“帖子”进行投标。为了实现这一点,我为模型“Bid”中的 post 字段创建了一个外键。

实际上,我想在“帖子”模型中使用自动生成的“id”将出价与特定帖子相关联。所以我在模板中将 get_absolute_url 放在 Post 'id' 旁边。我是 django 的新手,我不确定它是否适合我想要的。

如何将带有 post_id 的出价与模板中的特定帖子相关联,以便我可以获得各种类型 2 用户对特定帖子的出价金额?我将不胜感激帮助我解决这个问题。

这是我的代码:

模型.py:

class Post(models.Model):

    post_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
    from1 = models.CharField(max_length=20)
    timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)

    objects = PostManager()

    def __str__(self):
        return self.post_id

    def get_absolute_url(self):
        return reverse("posts:detail", kwargs="id": self.post_id)

    class Meta:
        ordering = ["-timestamp", "-Time"]

class Bid(models.Model):

    bid_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    post = models.ForeignKey(Post, default=uuid.uuid4, related_name='bids' )
    user = models.OneToOneField(settings.AUTH_USER_MODEL, null=True, blank=True, unique=False)
    amount = models.IntegerField()

    def get_absolute_url(self):
        return reverse("accept_bid", kwargs="bid_id": self.bid_id)

    def __unicode__(self):
        return self.amount

    def __str__(self):
        return self.amount

forms.py:

class BidForm(forms.ModelForm):
    // Defined a post field as ModelChoiceField
    post = forms.ModelChoiceField(queryset= Post.objects.all(), label="Post", widget=forms.Radioselect(), initial=0)
    amount = forms.IntegerField(help_text='Place the bid for a Post')

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super(BidForm, self).__init__(*args, **kwargs)
        self.fields['post'].queryset = Post.objects.all

    class Meta:
        model = Bid
        fields = ["amount"]

views.py:

def live_bid_truck(request, **kwargs):
    if request.method=='post':
        form = BidForm(request.POST or None)

        if  form.is_valid():
         bid = form.save(post)
         bid = form.save(commit=False)
         print(form.cleaned_data.get('amount'))
         bid.user = request.user
         bid.post = form.cleaned_data['post'] // Set my post here


         bid.save()
    else:
        form=BidForm()
        post_queryset = Post.objects.all()
        context = 
        "post_queryset": post_queryset, 
        "title": "List",
        'form': form,

    
        return render(request, 'loggedin_truck/live_bid_truck.html', context)

live_bid_truck.html

% for post in post_queryset %
<table class="table table-striped, sortable">
    <thead>
        <tr>

            <th>Load No.</th>
            <th>From</th>
        </tr>
    </thead>
    <tbody>
        <tr> // Returns the post_queryset with radio buttons
            <td >form.post </td>
            <td> post.from1 </a><br/></td>
        </tr> 
    </tbody>
</table>
<table class="table table-striped, sortable "  style="margin-top: 10px">
    <thead>
        <tr>
            <th> Amount</th>
        </tr>
    </thead>
    <tbody>
        <tr>     
            <form class="nomargin" method='POST' action='' enctype='multipart/form-data'>% csrf_token %
            <td>% render_field  form.amount  class="form-control" %</td>
        </tr>
     </tbody>
 </table>

<input type='submit' value='Post Bid'/></form>

% endfor %

更新 - 1:

Views.py:

def live_bids(request):
    post_queryset = Post.objects.all().prefetch_related('bids')
    bid_queryset = Bid.objects.all().order_by('amount')

    context = 
        "post_queryset": post_queryset,
        "bid_queryset": bid_queryset,
        "title": "List",
    
    return render(request, 'loggedin_load/live_bids.html', context)

live_bids.html:

% for post in post_queryset %
post.id
% for bid in post.bids.all %
bid.amount
% endfor %
% endfor %

【问题讨论】:

您可能想向我们展示您的表格。您使用的是 ModelForm 吗? @wobbily_col。我更新了我的代码。是的,我正在使用模型形式。我的模型表单中没有包含任何帖子字段。如果需要,我该怎么做? @wobbily_col。从过去的两天开始,我一直停留在这一点。我无法前进。你能帮我解决这个问题吗? 尝试将模板中的表单呈现为 form 而不是 % render_field form.amount class="form-control" %。 (对不起,我有点忙于发布正确的回复)。 【参考方案1】:

如果我理解正确,目标是能够在帖子上列出相关的投标人/投标?如果是这样,那么您可以使用select_related(如果您从孩子中选择父母)或prefetch_related(如果您正在进行反向查找)

1) 首先,在您的出价模型中,related_name 最好是“出价”,就像这样;

post = models.ForeignKey(Post, default=1, related_name='bids' )

2) 其次在def live_bid_truck(request): 内部进行这样的发布查询,这样您就可以在一个数据库命中中获取所有相关对象。;

Post.objects.all().prefetch_related('bids') 

3)然后在您的模板中,您可以使用可以访问帖子的相关出价

% for bid in post.bids.all % // In your case post is obj
     bid   // Access whatever you need from the bid like  bid.user 
% endfor %

您应该能够调用post.bids.all 并接收值,即使不通过following the backward relation 进行预取也是如此。如果您没有得到任何值,那么您可能没有正确设置它们。随着帖子数量的增加,prefetch_related 有助于提高性能。


来自您的代码

在您的BidForm 中没有对post 的引用,我不知道您的自定义 save() 方法中是否有它。当您按原样保存此表单时,post_id 将是默认值 1

# NO REFENCE TO post
class BidForm(forms.ModelForm):

 class Meta:
    model = Bid
    fields = ["amount"]  

同样在您的view 中,您也没有设置帖子。

def live_bid_truck(request):

    form = BidForm(request.POST or None)

    if  form.is_valid():
        bid = form.save(commit=False)

        print(form.cleaned_data.get("amount"))
        bid.user = request.user # YOU SET THE USER 
        bid.post = ?? # YOU DON'T SET THE POST HERE EITHER, 
                      # SO ALL YOUR BIDS HAVE THE DEFAULT POST id = 1
                      # DO YOU ACTUALLY HAVE POST with id = 1?

        bid.save()

        # WHAT HAPPENS IF YOU PRINT BID POST ID HERE ?? 
        # CHECK HERE IF YOU REALLY HAVE THE RELATED POST ID.
        print(bid.post.id)

【讨论】:

在我在 live_bid_truck.html 中的 BidForm 中输入金额后,该值将存储在我的数据库中。但我无法获得 live_bids.html 中特定帖子的金额值。我在问题中更新了我的代码。你能再帮我一次吗!!! 在你更新中,我看到你正在使用prefetch_related,它应该是select_related,因为你正在尝试关注外键关系。请参阅this question for the difference 同样在您的模型中,related_name 仍然看起来像 "posts"。如果related_name 仍然是"posts",则使用select_related('posts') 因为它是反向外键关系,所以我使用了 prefetch_related。无论如何我都不知道为什么我无法在 live_bids.html 中获得金额值。 假设你的Bid模型中有这个post = models.ForeignKey(Post, default=1, related_name='bids' ),你能试试Post.objects.all().select_related('bids')

以上是关于Python:如何在我的 Django 模板中传递外键的值?的主要内容,如果未能解决你的问题,请参考以下文章

Django将Python对象从视图传递到模板中的Javascript脚本

如何将变量从 python Django 传递到 HTML 模板

如何使用 django 动态访问会话中的值?

如何将 jquery datepicker 从模板传递到 python Django 中查看?

如何从 python 代码中调用 django 模板标签?

Django Python - 如何在一个 HTML 模板中显示来自不同表的信息