Multiplechoice widget with really big lsit - django

In my model Person can have more than one partner, so the ManyToMany Model is the only answer (this has to be ManyToMany for other reasons, so please don't think about changing it).
If I use default widget i got a list of all persons with selected one, two maybe three persons (which are partners of Person).
It would be ok, if the Person list is about 10-100 - and it works on test database. But my prod database has 10.000 persons or more, so the ModelMultipleChoice widget would be filled with 10.000 records, and finding the correct partner will last ages, and memory usage isn't trivial.
I need only to see names of partners with possibility to unset it from person, and some possibility to add new just typing name. The best solution is to show listbox with filtered names after typing three or four first letters, but any solution would be great.
With forms it would be easier, but I need it in admin, so I'd like to use django admin standards.

Related

I'm using django to build a website and I want to link tutors and students

I'm currently stuck with the best way of assigning tutors to students and then tutors can add lessons for these students and they can both see these lessons, but you can only assign one foreign key to the class "MyLessons". So I'm not sure whether it's worth creating a MyStudents class, storing students inside this (but their user is the same as tutors except is_tutor=false) and then for each student creating a MyLessons class that the tutor can add to.
I think I can make an approach I'm just worried it won't be very efficient or there will be some serious problems later on. Such as the other way was that each lesson would auto take in the tutors email (I set the username to email) and then when displaying the tutors lessons it would go through every lesson and display the lessons with a matching email... problems are though, if I reassign a student to a new tutor I'd like the new tutor to see the lessons but this would mean manually changing each and if there are too many lessons and students the process would get slow.
A Tutor has many students. A student potentially has more than one tutor. So at first glance that's a ManyToMany relational field.
One thing that's at first confusing is that the relationship is symmetric, but is defined on one object and only implicitly on the other. But the implicit and explicit fields both work the same, for manipulating a set of relationships.
class Tutor( models.Model)
students = ManyToManyField( Student, related_name='tutors', ...)
then
student_instance.tutors.add( tutor_instance)
tutor_instance.students.add( student_instance)
both accomplish the same. (In the simplest case. Read the doc for the exceptions).
It may or may not help to know that behind the scenes, Django is manipulating an implicit table whose objects have two fields, a ForeignKey to a student and a ForeignKey to a tutor. It can sometimes be useful to make this table explicit, so you can attach extra information to the relationship such as date created, who created it, etc. Look up the "through" option of ManyToMany if you want to do this.
Further examples here.

How to add fields dynamically to a form? - Implementing a django app to track order status

After a basic introduction to Python thanks to an edX course and a chat with a friend who told me about Django, I thought I could implement a solution for my laboratory. My goal is to keep track of every reagent order made by everyone of us researchers to the suppliers.
After one month I have a pretty decent version of it which I'm very proud of (I also have to thank a lot of StackOverFlow questions that helped me). Nonetheless, there's one requirement of the ordering flow that I haven't been able to translate to the Django app. Let me explain:
Users have a form to anotate the reagent (one per form) they need, and then it is passed to the corresponding manufacturer for them to send us an invoice. It's convenient that each invoice has several products, but they all have to: a) be sold by the same manufacturer, b) be sent to the same location and c) be charged to the same bank account (it's actually more complicated, but this will suffice for the explanation).
According to that, administrators of the app could process different orders by different users and merge them together as long as they meet the three requirements.
How would you implement this into the app regarding tables and relationships?
What I have now is an Order Model and an Order Form which has different CharFields regarding information of the product (name, reference, etc.), and then the sending direction and the bank account (which are ForeingKeys).
When the administrators (administratives) process the orders, they asign several of them that meet the requirements to an invoice, and then the problem comes: all the data has to be filled repeatedly for each of the orders.
The inmediate solution for this would be to create a Products Model and then each Order instance could have various products as long as they meet the three requirements, but this presents two problems:
1) The products table is gonna be very difficult to populate properly. Users are not gonna be concise about references and important data.
2) We would still have different Orders that could be merged into the same invoice.
I thought maybe I could let the users add fields dynamically to the Order model (adding product 1, product 2, product 3). I read about formsets, but they repeat whole Forms as far as I understood, and I would just need to repeat fields. Anyway, that would solve the first point, but not the second.
Any suggestions?
Thanks, and sorry for the long block!

Postgresql + Django: What is better between same strings or a many to many relationship?

I'm currently designing my data base using postgresql with Django and I was wondering: What is best practice - having several instances of the same model with the same value or a many to many relation ship?
Let me elaborate. Let's say I'm designing a store. The store sells items. Items can have one or many statuses (e.g. ordered, shipped, delivered, paid, pre-ordered etc.).
What would be a better practice:
Relating the items to their status via a many-to-many relationship, which will lead to one status having hundreds of thousand and later millions of relations? Will so many relations become problematic?
Or is it better for each item to have a foreignkey to their statuses? So that each status only has one item. And if I would like to query all the items that have the same status (e.g. shipped), I would have to iterate over all statuses with a common name.
What would be better, especially for the long term?
I would recommend going with a many-to-many relationship.
Hundreds of thousands or even millions of relations should not be a problem. The many-to-many relationship is stored as a table with id, item_id, status_id. SQL will be performant at querying the table either by status_id or item_id even if the table gets big. This is exactly the kind of thing it was built to handle.
Let me elaborate. Let's say I'm designing a store. The store sells
items. Items can have one or many statuses (e.g. ordered, shipped,
delivered, paid, pre-ordered etc.).
If many people will have this many itens you should use manytomany relations, better let django handle with this "third table", since this table just hold ids you can interate over them using reverse lookup, i do prefer using many to many instad of simple foreignkeys.
In your case, who you will handle when your User will hold many itens? like what if my User buy one potato and 2 bananas? you will duplicate the tuple in your User Table to tell "here he have the potato and in this second one he have the banana"? so you will be slave of Disctinct attribute while you still dirtying your main table User
...
class Item(models.Model):
...
class User(models.Model):
items = models.ManyToMany(Item)
So when i query my Item and my User will only bring attributes related to them... while if you use item inside of User Model you will have multiple instances of same user.
So instead of use User.items.all() you will use User.objects.filter(id=id)and them items = [user.item for user in User.objects.filter(id=id)]
Look how complex this get and makeing your database so dirty

Performance: Store likes in PostgreSQL ArrayField (Django example)

I have 2 models: Post and Comment, each can be liked by User.
For sure, total likes should be rendered somewhere near each Post or Comment
But also each User should have a page with all liked content.
So, the most obvious way is just do it with m2m field, which seems will lead to lots of problems in some future.
And what about this?
Post and Comment models should have some
users_liked_ids = ArrayField(models.IntegerField())
User model should also have such fields:
posts_liked_ids = ArrayField(models.IntegerField())
comments_liked_ids = ArrayField(models.IntegerField())
And each time User likes something, two actions are performed:
User's id adds to Post's/Comment's users_liked_ids field
Post's/Comment's id adds to User's posts_liked_ids/comments_liked_ids field
The questions are:
Is it a good plan?
Will it be efficient to make lookups in such approach to get "Is that Post/Comment` was liked but current user
Will it be better to store likes in some separate table, rather then in liked model, but also in ArrayField
Probably better stay with obvious m2m?
1) No.
2) Definitely not.
3) Absolutely, incredibly not. Don't split your data up even further.
4) Yes.
Here are some of the problems:
no referential integrity, since you can't create foreign keys on array elements, meaning you could easily have garbage values in an ID array
data duplication with posts having user ids and users having post ids means it's possible for information to get out of sync (what happens when a user or post is deleted?)
inefficient lookups in match arrays (your #2)
Don't, under any circumstances, do this. You may want to combine your "post" and "comment" models to simplify the relationship, but this is what junction tables are for. Arrays are good for use cases that don't involve foreign keys or the potential for extreme length.

Django PostgreSQL database table design, foreign keys, 1 to many

I have 4 tables in my database. The image below shows the rows and columns with the name of the table enclosed in a red box. 4 tables total. Am I going about the relationship design correctly? This is a test project and I am strongly assuming that I will use a JOIN to get the entire set of data on one table. I want to start this very correctly.
A beginner question but is it normal that the publisher table, for example, has 4 rows with Nintendo?
I am using Django 1.7 along with PostgreSQL 9.3. I aim to keep simple with room to grow.
Basically you've got the relations back-to-front here...
You have game_id (i.e. a ForeignKey relation) on each of publisher, developer and platform models... but that means each of those entities can only be related to a single game. I'm pretty sure that's not what you want.
You need it the other way around... instead put three foreign keys onto the game model, one each for publisher, developer and platform.
A ForeignKey is what's called a many-to-one relation. In this example I think what you want is for 'many' games to be related to 'one' publisher. Same for developer and platform.
is it normal that the publisher table, for example, has 4 rows with Nintendo?
No, that's is an example of why you have it backwards. You should only have a single row for each publisher.
yes you are correct in saying that something is wrong.
First of all those screen shots are hard to follow, for this simple example they could work but that is not the right tool, pick up pen and paper and sketch some relational diagrams and think about what are the entities involved in the schema and what are their relations, for example you know you have publishers, and they can publish games, so in this restricted example you have 2 entities, game and publisher, and a relation publish among them (in this case you can place a fk on game if you have a single publisher for a game, or create an intermediary relation for a many to many case). The same point can be made for platform and games, why are you placing an fk to game there, what will happen if the game with id 2 will be published for nintendo 64 ? You are making the exact same mistake in all the entities.
Pick up any book about database design basics, maybe it will help in reasoning about your context and future problems.