如何在不使用_set表示法的情况下遍历Django中指向对象的所有外键



我是Django的新手,但我正在开发一个遵循CPQ流或Configure、Price、Quote的应用程序。用户应该选择他们想要配置的产品以及相应的选项。一旦选择,程序应该查询外部定价数据库来计算价格。从那里程序应该输出定价&将文本数据转换为PDF报价。我能够使用从基本产品类继承的特定产品使应用程序工作。现在的问题是,我已经创建了第二个产品子类,我不能使用单数";related_name";。为了提高可读性,我省略了与下拉字段相关的列表,但我在下面发布了我的models.py文件。

有没有一种方法可以遍历指向具有外键的Quote对象的Product对象?我在SO上发现的许多与此相关的答案都可以通过指定"_设置";或";related_name";。我已经看到其他答案使用select_related((方法,但是,我似乎无法正确处理查询,因为程序不知道它需要查看哪个集合。报价可能有任何产品实例的组合,所以我不确定如何处理该查询。再说一次,我使用django不到6个月,所以我有点绿。我不确定我是否只是没有从根本上理解这里的大局。我考虑不使用继承,而是将Product作为一个独立的类,并将Compact或WRC信息保存到其中,这样我就可以使用一个";related_name";,但也认为这只会创建另一个仍然会失败的嵌套层。

如有任何帮助,我们将不胜感激!我肯定碰壁了。

型号.py

class报价(models.Model(:

project_name = models.CharField(max_length=256,blank=True)
customer_first_name = models.CharField(max_length=256,blank=True)
customer_last_name = models.CharField(max_length=256,blank=True)
company_name = models.CharField(max_length=256, blank=True)
address1 = models.CharField(max_length=256, blank=True, help_text ="Address")
address2 = models.CharField(max_length=256, blank=True)
city = models.CharField(max_length=256, blank=True, default="")
state = models.CharField(max_length=256, blank=True, default="")
zip_code = models.CharField(max_length=256, blank=True, default="")
country = models.CharField(max_length=256, blank=True, default="")
phone = PhoneField(blank=True)
email = models.EmailField(max_length=254,blank=True)
grand_total = models.FloatField(default=0)
create_date = models.DateTimeField(default = timezone.now)

class产品(型号.型号(:

class Meta:
abstract = True
price = models.FloatField(default=0)
total_price = models.FloatField(default=0)
quantity = models.IntegerField()
quote = models.ForeignKey('quote.Quote', on_delete=models.CASCADE)
quantity = models.IntegerField()

类紧凑型(产品(:

base_size = models.CharField(choices=size, max_length = 256)
filter = models.CharField(choices=filter_list, max_length = 256)
product_name = models.CharField(max_length=256,default="Compact")

WRC类(产品(:

base_size = models.CharField(choices=size, max_length = 256)
construction = models.CharField(choices=construction_list, max_length = 256)
outlet = models.CharField(choices=outlet_list, max_length = 256)
product_name = models.CharField(max_length=256,default="WRC")

我能够解决我的问题,但我想回答,以防有人遇到和我类似的问题。通过修改QuoteDetailView的get_context_data((方法,我可以动态地获取附加到报价实例的所有产品对象。我还需要使用django.contrib.admin.utils中的django库NestedObjects来获取报价实例的所有相关对象。我还在Product类中添加了一个时间戳字段,以便能够对它们进行排序。QuoteDetailView复制如下。

类QuoteDetailView(FormMixin,DetailView(:

model = Quote
form_class = ProductSelectForm

def get_context_data(self, **kwargs):
### collects related objects from quote 
collector = NestedObjects(using=DEFAULT_DB_ALIAS)
collector.collect([kwargs['object']])
### slice off first element which is the quote itself
related_objects = collector.nested()
related_objects = related_objects[1:]
### get context data for qoute object 
context = super().get_context_data(**kwargs)
context['now'] = timezone.now()
### if number of list items is above 0, then add them to the context
### and sort by timestamp
if len(related_objects) != 0:
context['items'] = sorted(related_objects[0], key=lambda x: x.timestamp)
return context

最新更新