Django ForeignKey模型表格

时间:2018-11-28 07:21:13

标签: django forms modelform

我是Django的新手。我有两个模型,其中一个模型具有外键。我在表单中使用模型表单,当我填写表单时,我的外键字段返回null。我想要的是在填写表单外键字段时,根据外键指出的内容进行填充。

型号:

class customerInfo(models.Model):
customerName = models.CharField(max_length = 50)
customerContent = models.TextField(max_length = 50)
createdDate= models.DateTimeField(auto_now_add = True)

def __str__(self):
    return self.customerName

class productInfo(models.Model):
    username = models.CharField(max_length = 50)
    passwd = models.CharField(max_length = 50)
    destIp = models.CharField(max_length = 50)
    hostname = models.CharField(max_length = 50)
    productName = models.CharField(max_length = 50)
    customer = models.ForeignKey(customerInfo,on_delete = models.CASCADE,null=True)

    def __str__(self):
        return self.productName

表格:

class customerForm(forms.ModelForm):
    class Meta:
        model = customerInfo
        fields = (
                "customerName",
        )

    class addProductForm(forms.ModelForm):
        class Meta:
            model = productInfo
            fields = (
                    "productName",
                    )


    class productInfoForm(forms.ModelForm):
            class Meta:
                    model = productInfo
                    fields = (
                            "username",
                            "passwd",
                            "destIp",
                            "hostname",
                    )

观看次数:

@login_required(login_url = "/")
def addCustomer(request):
    form = customerForm(request.POST or None)
    content = {"form" : form,}
    if form.is_valid():
        form.save()
        customerName = form.cleaned_data['customerName']
        return redirect("addproduct")

    else:
        return render(request,"addcustomer.html",content)

@login_required(login_url = "/")
def addProduct(request):
    form = addProductForm(request.POST or None)
    content = {"form" : form}
    if form.is_valid():
        global productName
        productName = form.cleaned_data['productName']
        return redirect("addproductinfo")
    return render(request,"addproduct.html",content)

@login_required(login_url = "/")
def addProductInfo(request):
    form = productInfoForm(request.POST or None)
    content = {"form" : form}
    if form.is_valid():
        p = form.save(commit = False)
        p.productName = productName
        p.save()
        return redirect("customer")
    return render(request,"addproductinfo.html",content)

因此,当我单击客户名称时,我想查看客户的产品。并非所有产品。 在执行此操作之前,客户ID字段必须完整。 我希望你能理解我。

2 个答案:

答案 0 :(得分:0)

如果要重用productInfo模型,则应将模型设为ManyToManyField而不是ForeignKey。据我正确理解,您希望拥有一种可以让多个客户“连接”到的产品,对吗?

了解更多-> https://docs.djangoproject.com/en/2.1/ref/models/fields/

更多-> https://www.revsys.com/tidbits/tips-using-djangos-manytomanyfield/

我的用法:

class EventVocab(models.Model):
    word              = models.CharField(max_length = 30)
    word_chinese      = models.CharField(max_length = 30,blank=True, null=True)
    explanation       = models.TextField(max_length = 200)
    example           = models.TextField(max_length = 100)
    word_audio        = models.FileField(blank=True, null=True)
    explanation_audio = models.FileField(blank=True, null=True)
    example_audio     = models.FileField(blank=True, null=True)

class UserVocab(models.Model):
    event_vocab  = models.ManyToManyField(EventVocab, related_name='event_vocab')
    current_user = models.ForeignKey(User, related_name="vocab_owner", on_delete=models.CASCADE)

在此示例中,UserVocab(在您的情况下为产品)只能连接到一个用户,但一个用户可以具有多个event_vocabs(产品)

答案 1 :(得分:0)

您的问题和代码示例不清楚。 首先,您应该将模型分解为几个用例:

  • 客户:客户列表,创建,读取,更新和删除(CRUD)客户
  • 产品:产品列表,创建,读取,更新和删除(CRUD)产品

您可以从客户列表中读取一个,然后在“显示的详细视图”上创建,更新或删除它。

您可以从产品列表中读取一个,然后在“显示的详细视图”上创建,更新或删除它。

从客户列表到产品列表的传递可以通过在客户列表上每行显示一个额外的按钮/链接来完成,这样您的按钮/链接就可以显示任何客户详细信息。

客户的PrimaryKey(PK)通过url定义传递给详细信息。

path('customer/<pk>', views.customer_detail_view, name='customer_detail'),

此URL仅用于显示。每个数据库操作也需要一个:创建,更新,删除。在下面找到您的客户的urls.py代码示例。您将需要相同的产品。

from django.urls import path
from . import views

urlpatterns = urlpatterns + [
    path('customer', views.customer_list_view, name='customer_list'),
    path('customer/add', views.customer_add_view, name='customer_add'),
    path('customer/<pk>', views.customer_detail_view, name='customer_detail'),
    path('customer/<pk>/upd', views.customer_update_view, name='customer_update'),
    path('customer/<pk>/del', views.customer_delete_view, name='customer_delete'),
    ]

请注意,create不会通过'pk',因为尚不知道...

从列表视图中调用“详细信息视图”是在您的html模板中完成

<tbody>
{% for i in customer_list %}
<tr>
  <td><a href="{% url 'customer_detail' pk=i.id %}">{{ i.customerName }}</a></td>
  <td>{{ i.customerContent|default_if_none:"" }}</td>
</tr>
{% endfor %}
</tbody>

参数由kwargs(dict)通过url传递,如果您使用ClassBasedView(generic.DetailView),它将被自动处理。如果不是,则必须抓住{@ {1}}这样的kwarg,最后一个从kwarg中删除“ pk”。您也可以使用args(不分配pk键)kwargs.get('pk') or kwargs.pop('pk')来传递'pk'。这也可以直接在模型的get_absolute_url函数中定义。     def get_absolute_url(self):         返回reverse_lazy('customer_detail',args = [str(self.id)]) 要么     def get_absolute_url(self):         return reverse_lazy('customer_detail',kwargs = {'pk':self.pk})

通过这种方式,您还可以管理'productName'全局变量,应该避免!顺便说一句,我不明白为什么您愿意分开创建productName和productInfo?为什么不将它们放在一起?

最后,如果要显示产品的多个可能的编码行,则应查看Django-FormSet。在Google上搜索FormSet教程,但这是一项高级功能。

具有5条可能的编码行的ProductFormset看起来像:

{% url 'customer_detail' i.id %}