Detailview对象关系 [英] Detailview Object Relations

查看:42
本文介绍了Detailview对象关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

; TLDR -找到一些解决方案后,我的最后一个问题是,如果有的话,我该如何访问与主要detailview模型相关的模型相关的模型?



我正在尝试使用通用的detailview返回对象及其相关对象。在此示例中,像mcdonalds这样的公司将拥有任何站点(或位置)。我希望detailview能够显示的是公司详细信息以及与公司相关的站点详细信息。我被卡住了。尽管我努力不寻求帮助,但仍无法从引用公司站点的模型中提取数据。我要去哪里错了?我已经用 SiteModel.objects.filter(company = 5)展示了ID为5的站点名称的所有公司在django shell中工作了。 / p>

models.py

 '' '
公司模型包含基本公司信息
'''

class CompanyModel(models.Model):
name = models.CharField(_('公司名称'),max_length = 255,空白=否)
网站= models.URLField(_('公司网站'),空白=真实)
因为= models.DateField(auto_now_add = True)
rate = models.DecimalField(max_digits = 5,decimal_places = 2,blank = False)

def __str __(self):
返回'%s'%(self.name)

class Meta:
ordering = ['name']
verbose_name ='Company'
verbose_name_plural ='Companies'

''
站点模型由一个公司的站点组成,因为
一些公司有多个站点可供我们使用。
'''


类SiteModel(models.Model):
company = models.ForeignKey(CompanyModel,on_delete = models.PROTECT)
地址= models.ForeignKey(AddressModel,on_delete = models.PROTECT)
phone = models.ForeignKey(PhoneModel,blank = True,null = True,on_delete = models.PROTECT)
distance = models.SmallIntegerField(blank) = True)

def __str __(self):
返回'%s-%s,%s'%(self.company,self.address.city,self.address.state)

类元:
ordering = ['company']
verbose_name ='公司站点信息'
verbose_name_plural ='公司站点'

views.py

  class CompanyDetailView(DetailView):
模型= CompanyModel
template_name ='customers / detail.html'

def get_context_data(self,** kwargs):
context = super(CompanyDetailView,self).get_context_data(** kwargs)
context ['sites'] = SiteModel.objects.filter(id = self.kwargs ['pk'])
返回上下文

urls.py

  url(r'^客户/(?P< pk> [0-9a-z-] +)/详细信息/$'、CompanyDetailView.as_view()、
name ='customer-detail'),

更新1:



我的模板显示了正确的公司,但仅1个网站,且该网站与公司无关。精氨酸它同时显示ID为5的公司和ID为5的网站。如何在此处正确连接点?



模板

 < ;! DOCTYPE html> 
< html>
< head>
< meta charset = utf-8>
< title>客户详细信息< / title>
< / head>
< body>
< div class = container>
{{object.name}}
{%for site in site%}
{{site}}
{%endfor%}
< / div>
< / body>
< / html>

更新2:



我能够可以通过取代get_context_data来解决此问题,而只是通过相关模型名称的 _set 后缀进行修改即可。 Django文档参考



模板

 <!DOCTYPE html> 
< html>
< head>
< meta charset = utf-8>
< title>客户详细信息< / title>
< / head>
< body>
< div class = container>
{{company.name}}
{company.sites.all中站点的百分比}
{{site}}
{%endfor%}
< ; / div>
< / body>
< / html>

但是,要采取的后续措施是,我该如何深入一层以上?继上述模型之后,我还有一个报告模型。但是,当我使用与上述相同的方法时,在第一个模型之后它似乎崩溃了。即我不能只使用 company.sites.reports



models.py

  class ServiceReportModel(models.Model):
report_number = models.UUIDField(primary_key = True,default = uuid .uuid4,editable = False)
site = models.ForeignKey(customers_models.SiteModel,on_delete = models.PROTECT,related_name ='reports')
request_number = models.ForeignKey(ServiceRequestModel,
on_delete = models.PROTECT,
null =真,
空白=真,
related_name ='s_report_number'

report_by = models.ForeignKey(main_models.MyUser,related_name ='报告')
报告日期=模型.DateTimeField(auto_now_add =真)
Updated_by =模型.ForeignKey(main_models.MyUser,空白=真,null =真,related_name ='+')
Updated_date = models.DateTimeField(auto_now = True)
设备= models.ForeignKey(customers_models.EquipmentModel,on_delete = models.PROTECT)
report_reason = models.CharField(max_length = 255,null = True)
time_in = models.DateTimeField(空白=真,null =真)
time_out = models.DateTimeField(空白= True,null =真)
actions_taken = models.TextField(null = False,空白= False)
建议= models.TextField(null = True,blank = True)

def get_absolute_url(self):
return reverse('service-report',kwargs = { 'pk':self.pk})

def __str __(self):
返回'%s-%s,%s'%(self.site.company,self.reported_date。 strftime('%d%B%Y'),self.equipment.name)

class Meta:
ordering = ['reported_date']
verbose_name ='服务报告'
verbose_name_plural ='服务报告'


解决方案

I能够得到一个解决方案一点帮助。我回去继承了get_context_data方法,并遵循此文档有关使用过滤器和双下划线表示法来扩展关系。

  class CompanyDetailView(DetailView): 
model = CompanyModel
context_object_name ='company'
template_name ='customers / detail.html'

def get_context_data(self,** kwargs):
context =超级(CompanyDetailView,self).get_context_data(** kwargs)
context ['sites'] = SiteModel.objects.filter(company = self.get_object())
context ['reports' ] = ServiceReportModel.objects.filter(site__company = self.get_object())
返回上下文


;TLDR - After some solutions discovered, my final question is how can I, if at all, access models related to models related to the main detailview model?

I'm trying to use a generic detailview to return an object and it's related object. In this example, a company like mcdonalds would have any sites (or locations). What I want the detailview to be able to show is the company detail, and the site detail related to the company. I'm stuck though. Dispite my efforts in not asking for help, I have not been able to pull the data from the model referencing the company sites. Where am I going wrong? I have sort of proven this to work in the django shell with SiteModel.objects.filter(company=5) showing all of the company with an ID of 5's site names.

models.py

'''
The company model consists of the base company information 
'''

class CompanyModel(models.Model):
    name = models.CharField(_('Company Name'), max_length=255, blank=False)
    website = models.URLField(_('Company Website'), blank=True)
    since = models.DateField(auto_now_add=True)
    rate = models.DecimalField(max_digits=5, decimal_places=2, blank=False)

    def __str__(self):
        return '%s' % (self.name)

    class Meta:
        ordering = ['name']
        verbose_name = 'Company'
        verbose_name_plural = 'Companies'

'''
The site model consists of sites of a company as
some companies have several sites that we will work from.
'''


class SiteModel(models.Model):
    company = models.ForeignKey(CompanyModel, on_delete=models.PROTECT)
    address = models.ForeignKey(AddressModel, on_delete=models.PROTECT)
    phone = models.ForeignKey(PhoneModel, blank=True, null=True, on_delete=models.PROTECT)
    distance = models.SmallIntegerField(blank=True)

    def __str__(self):
        return '%s - %s, %s' % (self.company, self.address.city, self.address.state)

    class Meta:
        ordering = ['company']
        verbose_name = 'Company Site Information'
        verbose_name_plural = 'Company Sites'

views.py

class CompanyDetailView(DetailView):
    model = CompanyModel
    template_name = 'customers/detail.html'

    def get_context_data(self, **kwargs):
            context = super(CompanyDetailView, self).get_context_data(**kwargs)
            context['sites'] = SiteModel.objects.filter(id=self.kwargs['pk'])
            return context

urls.py

   url(r'^customer/(?P<pk>[0-9a-z-]+)/detail/$', CompanyDetailView.as_view(),
       name='customer-detail'),

Update 1:

My template is showing the correct company, but only 1 site, and the site is not related to the company. Arg. It's showing both the company who's ID is 5, and the site who's ID is 5. How do I connect the dots correctly here?

template

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Customer Detail</title>
  </head>
  <body>
    <div class="container">
      {{ object.name }}
      {% for site in sites %}
        {{ site }}
      {% endfor %}
    </div>
  </body>
</html>

Update 2:

I was able to sort this out by not supering get_context_data, and just itterating through the _set suffix of the related model's name. Django Documentation Reference

template

  <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>Customer Detail</title>
      </head>
      <body>
        <div class="container">
    {{ company.name }}
    {% for site in company.sites.all %}
      {{ site }}
    {% endfor %}
        </div>
      </body>
    </html>

The follow up to this, however, is how do I go more than one layer deep? Following up with the above models, I also have a "reports" model. But when I use the same method as above, it seems to break down after the first model. i.e. I can't just use company.sites.reports.

models.py

class ServiceReportModel(models.Model):
    report_number = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    site = models.ForeignKey(customers_models.SiteModel, on_delete=models.PROTECT, related_name='reports')
    request_number = models.ForeignKey(ServiceRequestModel,
                                       on_delete=models.PROTECT,
                                       null=True,
                                       blank=True,
                                       related_name='s_report_number'
                                       )
    reported_by = models.ForeignKey(main_models.MyUser, related_name='reports')
    reported_date = models.DateTimeField(auto_now_add=True)
    updated_by = models.ForeignKey(main_models.MyUser, blank=True, null=True, related_name='+')
    updated_date = models.DateTimeField(auto_now=True)
    equipment = models.ForeignKey(customers_models.EquipmentModel, on_delete=models.PROTECT)
    report_reason = models.CharField(max_length=255, null=True)
    time_in = models.DateTimeField(blank=True, null=True)
    time_out = models.DateTimeField(blank=True, null=True)
    actions_taken = models.TextField(null=False, blank=False)
    recommendations = models.TextField(null=True, blank=True)

    def get_absolute_url(self):
        return reverse('service-report', kwargs={'pk': self.pk})

    def __str__(self):
        return '%s - %s, %s' % (self.site.company, self.reported_date.strftime('%d %B %Y'), self.equipment.name)

    class Meta:
        ordering = ['reported_date']
        verbose_name = 'Service Report'
        verbose_name_plural = 'Service Reports'

解决方案

I was able to get a solution with some help. I went back to super'ing the get_context_data method, and following this documentation regarding spanning relationships using filters and double underscore notation.

class CompanyDetailView(DetailView):
    model = CompanyModel
    context_object_name = 'company'
    template_name = 'customers/detail.html'

    def get_context_data(self, **kwargs):
            context = super(CompanyDetailView, self).get_context_data(**kwargs)
            context['sites'] = SiteModel.objects.filter(company=self.get_object())
            context['reports'] = ServiceReportModel.objects.filter(site__company=self.get_object())
            return context

这篇关于Detailview对象关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆