I am fairly new to Django, but it's fun. I built a table with billing information. Let's say I have table structure like this: id, date, price, money received, and so on.
Now, once in a while, I would like to update that table, because everything may have been filled in except for the receipt of the purchase price. Therefore I thought it to be cool to generate a html table with all the entries from the db table in it. Then in the last column there could be input fields so that I could fill in whether there was a payment or not. But I do not want to make separate entries for each bill. Instead it would be cool, just to fill in the last column at once and the just to click a button "update". And then all the fields in the db should get an update about the payment. But generic views like UpdateView seem to only apply to single objects (or data rows if this is a better name for it).
Could you give me an advice how to get such an update table in Django?
Best regards
You can bulk create a lot of object to easily.
# many to many example
book1 = Book(name='book1 ')
book2 = Book(name='book2 ')
book3 = Book(name='book3 ')
entry = Entry.objects.get(id=1)
entry.books.add(book1 , book2 , book3 )
# other example
books = []
for i in range(20):
books.append(Book(name="blog"+str(i), headline='tagline'+str(i)))
Books.objects.bulk_create(books)
Related
So my problem is coming from a poor understanding of the complexity of my query. A bit of a background story to this ask.
It's a car rental and search website, which started as a personal project of mine. I am using Django 2.1 for this, as well as Postgres.
The setup is as follows: I have a car model, which has an ID, a category, a car type, an engine etc. Secondly, there is an address table, that I use for all sorts of things.
What I would like to do now is the following:
I want to create Google Ads specific .csv files. This file needs a specific column with aggregated integers, in order to show 'related content' for the user. Meaning: You have seen Car A, here is a selection of related or similar cars in that area: Car K, O and Q.
I don't really have a problem making a csv from my data, but my problem is rather in constructing the query for this to work. I have the following as a first step:
cars = Car.objects
.select_all_related()
.only(
'id',
'name',
'address__city',
'address__city_area',
'images'
)
1
select_all_related joins the address table, because that's where the car is located. It also makes my only() call work, since I want to pull out specific fields
Select Related Doc Reference
2
only gives me only the fields I want, since I don't want to sent the whole model anyway, this also works.
Only Doc Reference
So selecting and getting the correct data is not the problem, but:
The real problem:
The following code should create a column in the table. This column should have aggregated IDs of the cars that are in a similar area (city, and city area). And this is sadly a requirement by the Google Ads thing I use.
def find_similiar_cars_in_same_city(cars: QuerySet):
"""Annotate the QuerySet with a field called similar_cars_ids containing
a list of ad IDs or None if there are none."""
similar_cars_queryset = Cars.objects.filter(
address__city=OuterRef('address__city'),
address__city_area=OuterRef('address__city_area'),
).exclude(id=OuterRef('id')).values_list(ArrayAgg('id'), flat=True)
# Hack: Remove GROUP BY that Django adds when adding ArrayAgg.
similar_cars_queryset.query.group_by = []
cars = cars.annotate(similar_cars_ids=Subquery(
similar_cars_queryset,
output_field=ArrayField(models.IntegerField())
))
return cars
And this kinda works. just takes forever. You also can see the comment I made in the code, that annotate() actually groups by which I don't really want here. I run everything locally and even just having 10 cars takes about 12 seconds. I'm unsure if im missing anything. It kinda works, but wont work for larger sample size. I ran it against a DB with roughly 14k cars and it just never finished.
So to summarize: I want to make a function that creates a column in the db with aggregated IDs of similar cars.
Anyone has a pointer on where to make this more efficient? And please ask if there are any more questions and I forgot to mention something!
Unless you're paginating over the results, it might be easier to handle it in python.
cars = Car.objects
.select_all_related()
.only(
'id',
'name',
'address__city',
'address__city_area',
'images'
)
cars_in_area_map = defaultdict(set)
for car in cars:
cars_in_area_map[(car.address.city, car.address.city_area)].add(car.id)
# Generate csv:
data = [
car.id,
car.name,
car.address.city,
car.address.city_area,
car.image,
{id for id in cars_in_area_map[(car.address.city, car.address.city_area)] if id != car.id},
]
If you need to paginate over them, you could try doing it via address:
data = []
addresses = Address.objects.prefetch_related('car_set')
for address in addresses:
cars = list(address.car_set.all())
for car in cars:
data.append([
car.id,
car.name,
address.city,
address.city_area,
car.image,
{c.id for c in cars if c.id != c},
])
(A Django rookie here)
For a "project" model I want to store some data. The data is about housing property. So, for example: Number of living spaces, on which floor those spaces are, and how big those spaces are.
Living-space 1 - Groundfloor - 50m2
Living-space 2 - First floor - 82m2
etc.
Because not every project object has the some amount of living spaces and some project object's also have a row called something like Shop-space or restaurant space I was wondering about a good approach to storing this data.
Basically I want to store a dynamically sized table in a model. Below is pretty good example:
Restaurant - Groundfloor - 147m2
Livingspace 1 - First floor - 55m2
Livingspace 2 - First floor - 110m2
Livingspace 3 - Second floor - 55m2
Livingspace 4 - Second floor - 110m2
Livingspace 5 - Third floor - 147m2
Now some projects will have only 2 maybe 3 living spaces and no Restaurant's etc. Others will have maybe up to 10 living spaces. I was thinking about creating 10 row fields. So I can put in comma separated values (or maybe JSONfield). Something like:
row_01 = models.CharField(max_length=100)
row_02 = models.CharField(max_length=100)
row_03 = models.CharField(max_length=100)
row_etc = models.CharField(max_length=100)
"Livingspace 1","First floor","55"
"Livingspace 2","Second floor","100"
etc
Would this be a correct approach for putting this table in the database? How about a JSONfield?
Also, in my model I have a field in which the number of housing-spaces has to be put in by the user. Therefore I was thinking if it's possible to dynamically create rows based on other fields in the model? So if the user is in the Django administration and enters 4 for the number of houses that the user only sees 4 rows in the Django administration.
No, that is not good practice.
From what I understand, the data can be included using two tables. In django, each model corresponds to a table, with fields as columns. So you just have to make a House model and another model Room with Foreign key relationship to the House model.
A simple example:
class House(models.Model):
name = models.CharField()
class Room(models.Model):
house = models.ForeignKey(House)
room_type = models.CharField()
area = models.CharField()
floor_no = models.IntegerField()
From this, each House model instance represents a house. Each Room instance represents the row you said earlier. By designing the models like this could make the filtering, querying​ very easy.
Room instances are linked to the House model through a foreign key relationship, which enables to create any number of rows according to the required specifications.
For more reference, try the docs
The kind of db schema depends on how you are going to use that data.
The fields (except primary key) who you want to aggregate (sum,count etc) , querying based on them will be directly placed as a column while fields that are dependent(dynamicity) on other columns can be come into JSON field.
Considering your use case , JSON Field can be a good approach because you might not want to query based on each and every data .
I want to create a database of dislike items, but depending on the category of item, it has different columns I'd like to show when all you're looking at is cars. In fact, I'd like the columns to be dynamic based on the category so we can easily an additional property to cars in the future, and have that column show up now too.
For example:
But when you filter on car or person, additional rows show up for filtering.
All the examples that I can find about using django models aren't giving me a very clear picture on how I might accomplish this behavior in a clean, simple web interface.
I would probably go for a model describing a "dislike criterion":
class DislikeElement(models.Model):
item = models.ForeignKey(Item) # Item is the model corresponding to your first table
field_name = models.CharField() # e.g. "Model", "Year born"...
value = models.CharField() # e.g. "Mustang", "1960"...
You would have quite a lot of flexibility in what data you can retrieve. For example, to get for a given item all the dislike elements, you would just have to do something like item.dislikeelements_set.all().
The only problem with this solution is that you would to store in value numbers, strings, dates... under the same data type. But maybe that's not an issue for you.
I have three tables for managing stock levels - Product, ProductGender and ProductType. I also have a table called OrderItem that defines what is being ordered from the database.
After I have my program insert values into the OrderItem table, it identifies how much is to be ordered after the user inserts the amount into a field.
My question is - how do I subtract the amount of stock ordered from the amount of stock in the table ProductType? I know I will need some form of DELETE statement but I'm not sure quite how to craft a sufficient statement.
You probably need an UPDATE rather than an DELETE. That being said, I would not advise to update the stock after having accepted the order. I feel it more manageable the other way around: update the stock, and accept the order only if there was enough items.
Something like that:
--> client place an order for 20 item id XXXX:
UPDATE ProductType SET amount = amount - 20
WHERE amount >= 20 AND item_id = 'XXXX';
^^^^^^^^^^^^^^^^^^
Please note that "guard" clause
That statement will either update 0 or 1 row. 1 row means "ok, stock updated". 0 means "not enough items left in stock". This is especially important in multi-user environment where you can have several concurrent updates of your stock for the same item.
After that only:
--> If 1 row updated
INSERT INTO OrderItem(..., amount) VALUES (....., 20);
Finally, in a real world application, you need to wrap all those statements in a transaction in case of unexpected failure after the stock update.
I dont know correctly what you are expecting.Assuming
If table ProductType --> type1 amount
Then inserting to table OrderItem n items of type1.So assuming that you have to decrease that much amount from ProductType
When you insert n amount into OrderItem,
Here you can use UPDATE
UPDATE OrderItem SET column_name = column_name - n WHERE ...
Update
update the stock, and accept the order only if there was enough items, is the good process steps.
Hope this helps
so I know of the model.objects.all() but is there a way that i could get all of the items for a certain part of that database? say I have a database of books and under that I have the author and illustrator fields that you can enter. what would I enter so that it returned a list of all the authors?
Write like
Books.objects.values('author').distinct()
You can check for distinct function in https://docs.djangoproject.com/en/1.3/ref/models/querysets/#distinct