Displaying 2-dimensional data array in django template - django

I have a bunch of woods and a bunch of properties, describing the wood. The property of a specific wood is given by Answer (basically answers = woods x properties):
class Wood(models.Model):
desc = models.CharField(max_length=63)
class Property(models.Model):
desc = models.CharField(max_length=63)
class Answer(models.Model):
desc = models.CharField(max_length=255)
wood = models.ForeignKey('Wood', related_name='answers', null=True, default=None)
property = models.ForeignKey('Property', related_name='answers', null=True, default=None)
Now I want to show my data in a table. There is one row for each wood and one column for each property.
My problem starts when I use the first row as header with all the properties (property.desc) and the first column with all the woods (wood.desc). I couldn't find a way to access an Answer for a given Wood and Property from inside the template. This would be easy, if I could access dictionary values by key with the key being a variable - but that's not possible in templates as far as I know.
I did find a way, which turns out increasingly ugly: I can create nested lists in the view and traverse them in the template. I simply rely on the fact that list items stay in order and thus the answers match the header row. It feels wrong to create this intermediate list structure while the actual data structure is as straightforward as this.
I hope someone knows a way to map my data structure directly in a template.

Related

django subquery with a join in it

I've got django 1.8.5 and Python 3.4.3, and trying to create a subquery that constrains my main data set - but the subquery itself (I think) needs a join in it. Or maybe there is a better way to do it.
Here's a trimmed down set of models:
class Lot(models.Model):
lot_id = models.CharField(max_length=200, unique=True)
class Lot_Country(models.Model):
lot = models.ForeignKey(Lot)
country = CountryField()
class Discrete(models.Model):
discrete_id = models.CharField(max_length=200, unique=True)
master_id = models.ForeignKey(Inventory_Master)
location = models.ForeignKey(Location)
lot = models.ForeignKey(Lot)
I am filtering on various attributes of Discrete (which is discrete supply) and I want to go "up" through Lot, over the Lot_Country, meaning "I only want to get rows from Discrete if the Lot associated with that row has an entry in Lot_Country for my appropriate country (let's say US.)
I've tried something like this:
oklots=list(Lot_Country.objects.filter(country='US'))
But, first of all that gives me the str back, which I don't really want (and changed it to be lot_id, but that's a hack.)
What's the best way to constrain Discrete through Lot and over to Lot_Country? In SQL I would just join in the subquery (or even in the main query - maybe that's what I need? I guess I don't know how to join up to a parent then down into that parent's other child...)
Thanks in advance for your help.
I'm not sure what you mean by "it gives me the str back"... Lot_Country.objects.filter(country='US') will return a queryset. Of course if you print it in your console, you will see a string.
I also think your models need refactoring. The way you have currently defined it, you can associate multiple Lot_Countrys with one Lot, and a country can only be associated with one lot.
If I understand your general model correctly that isn't what you want - you want to associate multiple Lots with one Lot_Country. To do that you need to reverse your foreign key relationship (i.e., put it inside the Lot).
Then, for fetching all the Discrete lots that are in a given country, you would do:
discretes_in_us = Discrete.objects.filter(lot__lot_country__country='US')
Which will give you a queryset of all Discretes whose Lot is in the US.

Newbie Creating Django models

I'm new to django and trying to understand how I might create my models. I'm building an app that can be used to create documents from a template. These documents can be of a number of different types, and contain generic sections as well as sections specific to each document type. I'm intending for the specific sections that the user can choose from (to include in their document), to change according to the document type they have chosen to create. Yet the generic sections will be used no matter what the document type.
I'm having a hard time getting my head round how I might build my models to achieve this. I've considered giving the document model and sections model a document type that can be set and referenced in html, matching the sections to each document:
class Document(models.Model):
document_type = models.CharField(max_length=50)
class Sections(models.Model):
document_type = models.CharField(max_length=50)
or adding in a document type model:
class Document(models.Model):
document_type = models.ForeignKey(DocumentType)
class Sections(models.Model):
document_type = models.ForeignKey(DocumentType)
class DocumentType(models.Model):
name = models.CharField(max_length=50)
But I'm worried that this will cause problems due to many documents sharing some generic sections. And so I wondered if I separate the generic and specific sections:
class GenericSection():
document_type = models.ManyToManyField(DocumentType)
class SpecificSection():
document_type = models.ForeignKey(DocumentType)
or even separate each document type into it's own app. I think I've got myself into a twist with this and would appreciate any feedback on whether there's a more appropriate way to approach this.
If a document can be of only one type, I would personally have that in it's own table. That way they are not duplicated everywhere.
Then your document table's document type should be a foreign key to the document type table (assuming a document can only have one type or a many to many relation to the document type table if a document can be more than one type)
foreign key's are a great way to make sure your table doesn't turn into a nightmare of pointing to the wrong values or dead values etc...

How do I create multiple One-to-Many relationships to the same table in Django?

So first off, I want to clarify that I am trying to make One-To-Many relationships, not Many-to-One. I already understand how ForeignKeys work.
For the sake of the discussion, I've simplified my models; they're much more field-rich than this in the real implementation.
I have a model, called a ColumnDefinition:
class ColumnDefinition(Model):
column_name = CharField(max_length=32)
column_type = PositiveSmallIntegerField()
column_size = PositiveSmallIntegerField(null=True, blank=True)
I think have a registry. Each registry has a separate set of columns for it's input and output definition. I've put the theoretical "OneToManyField" in there to demonstrate what I'm trying to do.
class Registry(Model):
input_dictionary = OneToManyField(ColumnDefinition)
output_dictionary = OneToManyField(ColumnDefinition)
created_date = DateTimeField(auto_now_add=True, editable=False)
A ColumnDefinition is only ever related to one Registry ever. So it's not a Many to Many relationship. If I put a ForeignKey on the ColumnDefinition instead to create a reverse relationship, it can only create a single reverse, whereas I need both an input and output reverse.
I don't want to have to do anything kludgey like adding a "column_registry_type" field onto ColumnDefinition if I can get around it.
Does anyone have any good ideas on how to solve this problem?
Thanks!
You can add two ForeignKeys on ColumnDefinition, one for input and one for output, and give them separate related_names:
class ColumnDefinition(Model):
...
input_registry = models.ForeignKey(Registry, related_name='input_columns')
output_registry = models.ForeignKey(Registry, related_name='output_columns')
You can then access the set of columns like registry.input_columns.
You can and should define two different ForeignKey fields on ColumnDefinition. Just make sure to specify a related_name value for at least one of them.
https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey.related_name

Sort order for model items in django admin

Say I have a model:
class Question(models.Model):
text = models.TextField(verbose_name=u'Вопрос', max_length=1024)
is_free_text = models.BooleanField(verbose_name=u'Ответ в виде текста?')
sort_order = models.PositiveSmallIntegerField()
is there a plugin or something for django admin to have list of models somewhere and move them up and down (or drag and drop) to define their sort order? I basically want every question to have a unique sort order so that they are sorted according to their sort_order where fetched.
There are lots of options but you will most likely have to tinker a bit with them. Here are some snippets (I'm not sure how well these will work):
http://djangosnippets.org/snippets/2306/
http://djangosnippets.org/snippets/2047/
http://djangosnippets.org/snippets/2057/
Some apps that claim to do it:
https://github.com/ff0000/django-sortable
https://github.com/centralniak/django-inline-ordering
If you are interested installing django-grapelli (which is a skin for the entire django admin) , you can make use of their sortable change list items

Handling presentation logic in Django templates

The description below is heavily simplified - it's only one part of a bigger problem that we are tackling but the innards can be safely left out for this question.
Suppose we have the following models: -
class Item(models.Model):
name = models.CharField(max_length=150)
value = models.DecimalField(max_digits=12,decimal_places=2)
class Person(models.Model):
name = models.CharField(max_length=150)
items = models.ManyToManyField(Item, through='AssignedItem')
class AssignedItem(models.Model):
person = models.ForeignKey(Person)
item = models.ForeignKey(Item)
value = models.DecimalField(max_digits=12,decimal_places=2)
So basically a person may be assigned zero, one, or more items and each assigned item's value may be overridden for a particular person by specifying the new value in the through model.
What we are aiming to achieve is an html table which has all the Item.name as its header row, with one extra column in that header row for Person.name.
Each Person may have a different set of Person.items assigned to them so it is expected that if a Person has not been assigned an Item, the corresponding cell for that Person will be blank (please see attached image).
The question is how to place the correct AssignedItem value in the corresponding column. We have a Queryset of Items that we are looping over in the template to create the header row, and then we have a list of lists containing each person's items. But how do we ensure that the correct AssignedItem is displayed under the corresponding Item header?
You mentioned you are constructing the list in the view,
We have a Queryset of Items that we
are looping over in the template to
create the header row, and then we
have a list of lists containing each
person's items.
When constructing this list, make the list an ordered list, where if a particular value exists, assign it and if it doesnt, then insert None.
ie, the list for Jake should look like [78, 45, None, 94, 72]
Edit:
Since reordering is an issue, use a dictionary with the item as index
ie, the values for Jake should look like {'Item1':78, 'Item2':45, 'Item4':94, 'Item5':72}
Well, the main issue was to ensure that the correct AssignedItem is displayed under the corresponding Item header.
I tried a lot of things in the template, but it did not offer too much room to maneuver. I ultimately created the "table" in the view then passed the string to the template for rendering.