简体   繁体   中英

Django Pass Model Field as Parameter to URL Stored in Another Model

I have three models:

class Entity(models.Model):
    entity = models.CharField(primary_key=True, max_length=25)

class Report(models.Model):
    report = models.CharField(max_length=50)
    report_link = models.CharField(max_length=300)

class Item(models.Model):
    entities = models.ManyToManyField(Entity, related_name='entities')
    report = models.ForeginKey(Report)

A view is built off of the Item model:

def item_list(request):
    items = Item.objects.select_related('report').prefetch_related('entities')
    return render(request, 'items/item_list.html', {'items':items})

This view gets routed to a template:

{% for item in items %}
  <tr>
    <td>
        {% for entity in item.entities.all %}
          {{ entity }}{% if not forloop.last %}, {% endif %}
        {% endfor %}
    </td>
    <td>{{ item.report }}</td>
    <td>{{ item.report.report_link|urlize }}</td>
  </tr>
{% endfor %}

This line ( <td>{{ item.report.report_link|urlize }}</td> ) manifests like this in the browser:

https://server.domain/reports/specificReport?entity=

How would I pass the entities into the URL to filter the report? The desired result would look like this:

https://server.domain/reports/specificReport?entity=12345

...or if there are multiple entities for one item :

https://server.domain/reports/specificReport?entity=12345,56789

Each report in the Report model has a link, but the link does not necessarily take the entity parameter, so it wouldn't be ideal to globally change all links (ie through jQuery or some other JS). However, there is JS running on this page, so it is possible to use that...although I think a Django option might be best.

One thing I've thought about is adding an indicator to the Report model that flags whether entities should be added to the link...but this doesn't solve the main problem of attaching one model field to the end of another and "urlizing" both of them together.

How about a model method to create the link? The Django docs mention the following about using model methods, which is applicable to your use case

This is a valuable technique for keeping business logic in one place – the model.

Meaning you don't need to dig though your templates and template tags to see how an Item's report link is generated -- you can see it all in models.py

Something along the following could be a place to start

class Item(models.Model):
    entities = models.ManyToManyField(Entity, related_name='entities')
    report = models.ForeginKey(Report)

    def get_report_link(self):
        link_text = self.report.report_link
        if self.entities.count() > 0:
            link_text + "?entity={}".format(','.join([entity.id for entity in self.entities.all()]))
        return link_text

and then in your template: change item.report.report_link|urlize to item.get_report_link

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM