I need to have following table format in HTML:
My question is, how I should organize my Python data correctly so that I can implement this following table format in a clean, Pythonic way. All images belong to the certain version, thus it's important that image is in the right column (order matters). And some versions don't have all (or any) images so in that case, I'll check if "image == None" and show "?" etc. instead of the image. Thus, also 'empty' slots should be saved to data.
Note: I'm doing this with Django and I use Django templates to render this. Ideally, I could do something like following in the template:
<table>
<thead>
<tr>
{% for version in data.versions %}
<th>{{ version }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for image in data.images %}
<tr>
{% for file in image.files %}
{% if file == None %}
<td>No image</td>
{% else %}
<td>{{ file }}</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
Update: the problem is really how to organize data correctly in the backend. I need to manually initialize a list of versions (Version1, Version2, etc.) I want to put to data and create columns for those. Ordering is important so I need to keep that. Then I'll search for certain Objects which have X amount of images, which all have a certain version. Then I need to loop over those objects (for object in objects) and loop over images of the certain object (for image in object.images) and I should append each image to the column of certain version (add to column where "key" etc. == image.version). If there is no image for certain column, then value should be "None" etc.
I could implement this with list of lists for example:
data = [
['Version1', 'Version2', etc.],
['image',None, etc.],
['image', 'image', etc.],
etc.
]
But I'm pretty sure there is a better way to implement that in Python. So any better suggestions are very welcome.
Update 2: Django models could be like following:
class Version(models.Model):
name = models.CharField(max_length=255)
class Image(models.Model):
file = models.ImageField(upload_to='images')
version = models.ForeignKey(Version)
class Object(models.Model):
images = models.ManyToManyField(Image)
Something like this:
data_versions = { v1 : [img1, img2 ...], v2: [img1, ....]}
There is a better way.
First create a Model (database table) for your data and store everything there. You will have more power in representation of your data that way.
Models.py
class VersionImage(models.Model):
version_number = models.IntegerField()
image_1 = models.ImageField()
image_2 = models.ImageField()
image_3 = models.ImageField()
(I'm making a lot of assumptions on what your data looks like, so might want to change these based on your needs)
A better option (if you're going to have an array of images) would be to store all Images in one model, and make a M2M to your version table:
class ImageModel(models.Model):
image = models.ImageField()
class VersionModel(models.Model):
version_number = models.IntegerField()
image = models.ManyToManyField(ImageModel)
Then you can put the logic you want on the "Form/View" before sending it to your HTML template.
When working with Django, try to put everything on the backend and use HTML just for rendering the data that is already sorted and ready to present.
Let me know if you want me to elaborate on any of the above.
Related
I will try my best to be as concise as possible.
In my back end, I have a list of dictionaries saved to a variable. Each dictionary represents a post from reddit and includes the score, url, and title.
Respectively, the template will loop through this list and then return the values of each of these keys to the user like so:
<table>
<tr>
{% for x in data[0:5] %}
<td>
{{ x['score'] }}
{{ x['title'] }}
<br>
<a href='/add_to_favorites'> Add To Favorites </a>
</td>
{% endfor %}
</tr>
</table>
As you can see, there's an tag which is linked to a function on my utils.py that is attempting to save the respective dictionary to the database (I have a model that represents the url, title, and score).
I feel as though my template is not representing the dictionary in the correct way, for my link to include the html as when it is pressed I receive a 404 error (though I have this route already defined in views.py - '/add_to_favorites' which calls my 'save_post' function).
def save_post():
data = get_info()
for post in data:
fav= Favorite(title=post.get('title'), url=post.get('url'), score=post.get('score'), user_id=current_user.id)
db.session.add(fav)
db.session.commit()
return redirect(url_for('favorites'))
and:
#app.route('/add_to_favorites')
#login_required
def add_to_favorites():
return save_post()
Am i going about this the wrong way? How can i make sure that the link/button is associated with only the html of the that it is included in?
Just need some guidance into the right direction here, not necessarily the code to fix it. Thank you
Here is the problem, I'm a bit lost with foreignkey, i've seen a lot of post and i don't understand everything.
I have a item table:
class Item(models.Model):
title = models.CharField(max_length=150)
slug = models.SlugField(max_length=100)
price = models.IntegerField()
stock = models.IntegerField()
description = models.TextField()
image = models.ImageField(upload_to=item_file_name)
There is an image wich is the principal. On my index when I list all my item I want to see the image of each item. But when I click on the item I want to see all of the image of this item (in another view). So I've done this.
class ImageOfItem(models.Model):
picture = models.ImageField(upload_to=item_file_name_for_image)
item = models.ForeignKey('Item')
I don't know if it's good but it's working. I can add an item with a picture on the admin panel. And then I can add an image and attach it to the item.(it works, the best way would be to be able to upload all the image when creating the item but I prefer to start easy).
So know everything is save as I want. But I don't know how to display all the images.
My view looks like this:
def view_item(request, id, slug):
item = get_object_or_404(Item, id=id)
return render(request, 'ecommerce/view_item.html', locals())
I don't know if I have to get images too or if django already done it. and there is no var_dump so no way to know if it's in my variable item
my template:
{{item.title}}
{{item.description}}<br>
{{item.price}}<br>
{{item.stock}}<br>
<img src="{{ item.image.url }}"><br> //principal image it works !!
{% for img in item.ImageOfItem %}
<img src="{{ img.picture.url }}"><br> //**all the image I want to display too (but don't know how)**
{% endfor %}
all the image I want to display too (but don't know how)
You should follow relationship backward from Item to ImageOfItem:
{% for img in item.imageofitem_set.all %}
<img src="{{ img.picture.url }}"><br>
{% endfor %}
A picture is worth a thousand words. Here is what I'm trying to accomplish:
This is simple enough to do by just manually creating a table within the template like so:
<form>
<table class="table">
<thead><tr><th>{% trans 'Name' %}</th><th>{% trans 'Available Quantity' %}</th></tr></thead>
<tbody>
{% for p in products %}
<tr><td>{{p.name}}</td><td>{{p.available}}</td><td><input name="{{p.id}}" type="number" /></td></tr>
{% endfor %}
</tbody>
</table>
<form>
However, doing it this way makes it a hassle to deal with the submitted form data as well as do error validation.
I'd prefer to do it in a django form (formset seems more suitable). I've tried this approach but that doesn't make what i want any easier to accomplish.
Here's a minified version of my (relevant) models:
class Product(models.Model):
name = models.CharField("Name", max_length=50)
class OrderItem(models.Model):
product = models.ForeignKey('Product', verbose_name=_("Product"))
quantity = models.FloatField("Quantity")
Is there an elegant way to do this in django that I'm not considering?
Previously I had a client summary list in a table. In one column I had a list of object types and in another, I had the quantity of that object type.
#login_required
def client_summary(request, client_id):
client = models.Client.objects.get(pk = client_id)
items = client.storageitem_set.all()
tape_and_film_items = client.storageitem_set.filter(type="1")
total_tape_and_film_items = tape_and_film_items.count()
electrical_equipment_items = client.storageitem_set.filter(type="2")
total_electrical_equipment_items = electrical_equipment_items.count()
storage_office_equipment_items = client.storageitem_set.filter(type="3")
total_storage_office_equipment_items = storage_office_equipment_items.count()
<table cellspacing="15" style="float: left">
<tr><th scope="col">Type</th><th scope="col">Quantity</th></tr>
</tr><td>Tape + Film</td><td align="center">{{total_tape_and_film_items}}</td></tr>
</tr><td>Electrical Equipment</td><td align="center">{{total_electrical_equipment_items}}</td></tr>
</tr><td>Storage Office Equipment</td><td align="center">{{total_storage_office_equipment_items}}</td></tr>
</table>
Now this would work, but there is a problem. I did not knew earlier that users could add their own storage object from a form in my web app. If they try add a new object type, it will not show up in my client summary unless I explicitly write up an django query in a view passing a variable in a template. If there was no form to add an object type, this would have worked.
So in my template now I have this now in the type column. This part will work because all I really need to do is list all the storage item objects regardless of whoever client it is.
views.py
item_type = models.StorageObject.objects.all()
template
{% for item in item_type %}
{{item.title}}
{% endfor %}
But in the quantity column I can't seem to count. Returns nothing.
{% for item in items %}
{{item.type.count}}
{% endfor %}
If you need to display some info of items for every tag, you can use regroup tag. If you want only quantity, use Count aggregation function.
this is my model:
class Geo(db.Model):
entry = db.ListProperty(db.Key)
geo=Geo()
geo.entry.append(otherModel.key())
and the html is :
{% for i in geo.entry %}
<p>{{ i.title }}</p>
{% endfor%}
but it show nothing,
i think maybe should :
class Geo(db.Model):
entry = db.ListProperty(db.Model)
geo=Geo()
geo.entry.append(otherModel)
but it show :
ValueError: Item type Model is not acceptable
so , how to make the html shows the right thing.
thanks
You can't use that template (or the like) to show the model directly, but you can easily prepare a context with a list of models by simply calling db.get on the list of keys -- e.g., have {'entries': db.get(listofkeys), ... at the start of your context dictionary, and for i in entries in the template.