How to create element in another model with django - python

I have a small question. That is actually making me scratch my head.
So in my Database, I have the following models:
Activity
Bill
Clients
I think you are all seeing the relationship I am trying to create :
A Bill has one client and one or more activities. Here is the trick to make this whole thing user-friendly I am trying to create Bills (with the url: Bill/new) that can be edited manually. So the user is sent to an HTML page with the basic Bill template and he has a table that can add some rows with the activity the time spent and its cost.
There are three things I am trying to achieve.
Generate automatically the ID of the Bill (it should be pk of Bill) but it seems it's not generated until I have pressed on save.
When I save a Bill I want to save also the activities I have entered manually.
When I save the Bill I would like to save it as a Word or PDF document in the database.
Are these possible?
Thanks all for reading and helping I am banging my head to figure out how to do all of this and I am quite a newbie so any help is welcome.
Thanks in advance.

One way would be for the Bill objects to have a boolean field in_preparation. There would be a sequence of forms involved. The first would create a minimal Bill object with in_preparation=True. Then the related objects could be created and linked to this Bill. The final stage would be to display the entire bill and related objects for checking, with options to go back and edit, or "Confirm and issue to customer". This latter would set in_preparation=False and generate the pdf and word files.
If all the necessary information is already available and you are just asking how to use a ModelForm in this circumstance, the answer is obj = form.save( commit=False). It's then up to you to call obj.save() once you have finished updating it or its related objects More information here
If you are saving a bunch of objects at once and want to be sure it's all-or-nothing (the latter if something throws an exception), you need a Django transaction.

Generate automatically the ID of the Bill (it should be pk of Bill) but it seems it's not generated until I have pressed on save.
For bills and any other "real world"-like documents you'd probably better define some custom number generator to detach number from the auto-id and to be able to generate numbers using more complex patterns (eg AB-12345/321).
But in any case whether you choose to use auto-id or a custom generator the most simple way to garanty existence and uniqueness of that id/number is to save bill instance first. Also this approach has some additional pros.
When I save a Bill I want to save also the activities I have entered manually.
You can use django formsets for this (assuming that your bill and activity models have fk or m2m relation)
https://docs.djangoproject.com/en/3.2/topics/forms/formsets/
When I save the Bill I would like to save it as a Word or PDF document in the database.
I'm not really sure if it is a good idea to store pdf or word files in db somehow.
In my opinion there are better ways
Generate pdf (word, excel etc) docs from data on request
Store as files in filesystem.
In this case files shouldn't be stored in publicly accessible
dirs (like media and static) and should be served instead with
FileResponce with proper access checks in the view

Related

How to save the number of registered users in mongodb?

I have a problem and I am looking for a solution. I want to save the number of users registered in mongodb. For example, in django, the admin page has the number of registered users, and all other data is saved there. I want it to be saved in mongodb database instead of showing it on admin page, because my other data is also saved in mongodb. How do I do this? Should I make separate a class in models.py or something else.
You are asking a wrong question, because you should not do that.
The number of users is User.objects.count() maybe with a filter to count only active users.
Never save data that can be calculated/derived from other data, as this will just lead to inconsistencies. Why do you want to save it? You'd have to make sure the number is updated every time a new user is added/deleted and it's so easy to forget places in your code where this might happen.

Show change log history for model instance using django-reversion

Using:
django 1.10 reversion 2.0.8.
My question is how to show a nice list of changes done to a given model instance. By that I mean that the user can quickly see a list of all the changes (new values for fields) in all revisions. He doesn't need o see all the fields only the new values of the changed ones.
So I found that a good tool for storing changes is django-reversion. However, I cannot find a solution for my problem which as I mentioned is to show a nice change-log history for a given model instance.
I found solution that can compare two revisions django-reversion-compare, but that is not what I am looking for. Maybe there is a better tool for that ?
The task is too quickly show to user what was changed by who and when. The model is simple and doesn't store a lot of data. It does store however foreign keys.
I was also looking to do the same, and after reading up a few SO posts, docs etc., it seems I had to roughly choose the solution from one of the following 3 approaches:
1) Fetch the existing model instance before saving the new model instance. Compare each field. Put the changed field in reversion.set_comment('(all changes here)'). Continue with saving the model instance.
2) Save a copy of the old fields separately in model's __init__() and later compare the new fields with them (in model's save()) to track what changed. Put the changed fields in reversion.set_comment('(all changes here)'). Continue with saving the model instance. (This approach will save a DB lookup)
3) Generate a diff using django-reversion's low-level API and integrate with the Admin somehow
I ended up using django-reversion-compare which worked great for me showing the edits wiki-style (which may be using (3) above anyways)
django-reversion's developer also confirmed (3) as a better option which also avoids race condition.
If you would like to explore different options, this is a great SO post with lots of good ideas with their pros/cons.
(I am also on Django 1.10)

Django custom user VS user profile

I'm currently using Django 1.5.1 and using a custom user as described in the official documentation. I realized everything is stored under one table, the auth_user one.
My question is, why is it better to have everything in one big table, instead of having 2 tables like it used to be prior to 1.5 by using a user_profile table for all additional data? It seems smarter the way it used to be, in case we want to add 20 new fields for information about the user, it is weird to have everything in auth_user.
In my case, for now I have class MyUser(AbstractUser) with 2 additional fields gender and date_of_birth, so it's all good with this, but now I would like to have many other information (text fields) like "favorite movies", "favorite books", "hobbies", "5 things I could not live without", etc. etc., to have way more information about my user. So I was just wondering if I should put that under MyUser class, or should I define a UserProfile one? And why?
Thanks!
When you have it all in one table, then database access is faster. With the old way you had to join on the auxiliary table to get all the information of the user.
Usually when you see a One-to-One relation, it would be better just to merge them in one table.
But the new custom User model solves also another problem, which is what atributes a User should have? What attributes are essential for your application? Is an email required? Should the email be also the username with which a user logs in?
You couldn't do these stuff before this feature was introduced.
Regarding your question about where to put additional user information like "hobbies" and such, it really depends on how often you will query/need this attributes. Are they gonna be only on the user's profile page? Well then you could have them in a seperate table and there wouldn't be much problem or performance hit. Otherwise prefer to store them on the same table as the User.

Python - Django - How to handle a multiple page form correctly

I have an application that is used to store vehicle information. I created a Vehicle Model which has many foreign keys including a Consumption Model, Capacity Model, Tires Model, Fuel Model etc.
Multiple Page Form:
When a user wants to add a vehicle to the inventory I wanted to use a multiple page form to break up the steps. So, for example, the first step would be the Vehicle modelform and the second step would be the Fuel modelform. The problem I am running into is storing modelforms over multiple pages without using formwizard.
My Thoughts:
There seems to be no information on how to do this, am I the only one who wants to do this or is the solution blatantly obvious? In other languages I would have stored all the forms in a session and saved them at the end of the process. It seems you can't store a modelform in a session because I get a pickling error (unless I serialize it perhaps?) so I assume that is a no-no. I could save the modelform of a given page to the database before going to the next step but that has multiple issues. i.e. what if the user stops halfway through?
Any explanation on the normal way this is done, or if it is ok to serialize modelforms would be greatly appreciated.
You are looking for the form wizard:
Django comes with an optional “form wizard” application that splits forms across multiple Web pages. It maintains state in hashed HTML fields so that the full server-side processing can be delayed until the submission of the final form.
You might want to use this if you have
a lengthy form that would be too
unwieldy for display on a single page.
The first page might ask the user for
core information, the second page
might ask for less important
information, etc.
More details in the docs.

Processing forms that generate many rows in DB

I'm wondering what the best approach to take here is. I've got a form that people use to register for a class and a lot of times the manager of a company will register multiple people for the class at the same time. Presently, they'd have to go through the registration process multiple times and resubmit the form once for every person they want to register.
What I want to do is give the user a form that has a single <input/> for one person to register with, along with all the other fields they'll need to fill out (Email, phone number, etc); if they want to add more people, they'll be able to press a button and a new <input/> will be generated. This part I know how to do, but I'm including it to best describe what I'm aiming to do.
The part I don't know how to approach is processing that data the form submits, I need some way of making a new row in the Registrant table for every <input/> that's added and include the same contact information (phone, email, etc) as the first row with that row. For the record, I'm using the Django framework for my back-end code.
What's the best approach here? Should it just POST the form x times for x people, or is there a less "brute force" way of handling this?
Django includes FormSet for dealing with exactly these challenges. Using a FormSet you can create multiple forms for creating or updating information. There's even possible to generate the FormSets from a Model. http://docs.djangoproject.com/en/dev/topics/forms/formsets/ and http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#id1 are great resources.
Now, for creating more forms on the fly, you need some javascript magic. I've done this on work projects using jQuery which made it a lot simpler. The basic idea is create a new form with the correct inputs and change the hidden metadata in the formset form so it will now how many forms to process. The admin implements this when using multiple inline forms so I suggest looking there for code as it is a bit tricky to get right.

Categories

Resources