User-created Record Fields - python

I am creating a web-app w/ Flask + Flask-WTF that has CRM-like features as a project. My current database (MongoDB) structure is I have:
Users who can login,
People who are assigned to users, and
Records who are assigned to people.
People have various fields to be filled out (Name, Phone Number, Email, etc).
I want Users to be able to create custom fields for people. I am trying to plan out how to implement this from a database design perspective. My initial thoughts are to:
For each field created, add a new field without a value for each People assigned to the user.
Use a for-loop to dynamically create the form class by looping through each field-value in my database and excluding non-required ones.
Use a for-loop to dynamically output the web form by looping through each field-value in my database and excluding non-required ones.
Another idea I have is:
For each field created, add the custom field, with a parentRecord equal to the User ID to a new MongoDB collection.
Use a for-loop to create the form class & web form dynamically, but I wouldn't need to exclude non-required ones as the only fields in the collection would be the custom ones, and wouldn't include any special data points that don't get displayed.
So my questions are:
Will my ideas above work?
Which one is better?
Is there a better way?

I decided to create a customfields MongoDB collection that has a parentRecord as the User.
I faced a few challenges:
I had to dynamically create a form via flask WTF. I ended up using wtforms_dynamic_fields to accomplish this. I then used a for-loop to dynamically generate each form in Jinja. I simply queried the customfields DB where the parentRecord matched the logged in User, and then created custom fields based upon the values saved in customfields.
The second issue I faced was getting the data from the submitted form and then building a MongoDB-friendly list to insert a new record with when creating new record. This was accomplished by using request.form.items() and iterating through them and using list.update() to add all of my required fields to a list.

Related

How to use the data about objects modifications in Django?

Django stores a history of the modification for every object, it is something we can access to through the Django admin:
It contains data about when the object was created/modified, the user who performed the action and the timestamp of the action:
By giving a look at the database, I can guess this data is stored in a default table called django_admin_log:
I am wondering if we can make use of this data in any way through the instance of a model ? I got used to adding manually my timestamps on every models through an Abstract Base Class, but I am wondering if it is useful in any way ?
Or this table records only the modification taking place in the Django admin panel, which would makes the custom timestamp still needed for when the models instance were to be updated outside it.
The history is only related to actions done in the admin view. To add metadata you can also use model_utils, which also offers some other handy functionalities: https://django-model-utils.readthedocs.io/en/latest/
Let us assume every action would be stored in a history table. This would indicate that you always have make a join in the db to get a view where each row also has created and updated information. This is quite some overhead. Therefore, keep it simple and add the timestamp to each model :)

How to provide different sets of data to different users in django?

I'm a newbie to the django framework and trying to make a watchlist for stocks. I've already made the crux of the webapp, where-in, a user can search for a quote and add it to their watchlist, along with relevant data about that quote.
What I want to do now is, to save the separate watchlists that different users are creating (after creating an account on my site) and upon logging in to my site, they can view their personalized watchlist and edit it.
I'm using a model for storing the data for the watchlist quotes and looking for a way to provide the different personalized watchlists depending upon the logged in user.
Can anyone give me a lead on how to employ the logic for this? Do I need to use two data bases - one for the data of the users and the other one for storing the respective user watchlists? If yes, how do I connect everything?
EDIT: Ever used a stock investment app? The way every user/customer can log in to their account and make/edit and save their watchlists in the app - that is the functionality I want to implement. How/Where do I store so many watchlists?
use 'request.user' from your view, to know the user who sent the request and return the corresponding watchlist

Create a dynamic admin site

I want to create a dynamic admin site, that based on if the field is blank or not will show that field. So I have a model that has a set number of fields, but for each individual entry will not contain all of the fields in my model and I want to exclude based on if that field is blank.
I have a unique bridge identifier, that correlates to each bridge, and then all of the various different variables that describe the bridge.
I have it set up now that the user will go to a url with the unique bridgekey and then this will create an entry of that bridge. So (as i am testing on my local machine) it would be like localhost/home/brkey and that code in my views.py that corresponds to that url is
However, not every bridge is the same and I have a lot more variables that I would like to include in my model but for now I am just testing on two : prestressed_concrete_deck and reinforced_concrete_coated_bars. What I want is to dynamically create the admin site to not display the prestressed_concrete_deck variable if that field is blank. So instead of displaying all of the variables on the admin site, I want to only display those variables if that bridge has that part, and to not display anything if the field is blank.
Another possible solution to the problem would be to get that unique identifier over to my admins.py. I cant figure out either how to get that individual key over as then I could query in the admins.py. If i knew how to access the bridgekey, I could just query in my admins.py dynamically. So how would I access the brkey for that entry in my admins.py (Something like BridgeModel.brkey ?)
I have tried several different things in my admin.py and have tried the comments suggestion of overwriting the get_fields() method in my admin class, but I am probably syntactically wrong and I am kind of confused what the object it takes exactly is. Is that the actual entry? Or is that the individual field?
Just override the get_fields method in your ModelAdmin class.
You can check the obj is passed as function argument so you can check which fields are empty. The function needs to return a tuple so, you would check if field1 is None and then return (field1, field2, field3) or (field2, field3) depending on the value of field1.
I was using Django 1.6 which did not support overriding the get_fields method. Updated to 1.7 and this method worked perfectly.

Setting values to the output of a formset in Django

This question is somewhat linked to a question I asked previously:
Generating and submitting a dynamic number of objects in a form with Django
I'm wondering, if I've got separate default values for each form within a formset, am I able to pre-populate the fields? For instance, a form requiring extra customer information to be pre-populated with the users names? In cases like adding an email field to an already existing table, and updating many of them at once.
Does Django provide an easy way to do this?
Pass in a list of dicts which contain the default values you want to set for each form:
http://docs.djangoproject.com/en/dev/topics/forms/formsets/#using-initial-data-with-a-formset

Django Admin relations between tables: save database updates in several tables

I am using Django admin for managing my data.
I have a Users, Groups and Domains tables.
Users table has many to many relationship with Groups and Domains tables.
Domains table has one to many relationship with Groups table.
and when I save the User data through admin I also need some addtional database updates in the users_group and the users_domains table.
How do I do this? Where do I put the code?
I think you are looking for InlineModels. They allow you to edit related models in the same page as the parent model. If you are looking for greater control than this, you can override the ModelAdmin save methods.
Also, always check out the Manual when you need something. It really is quite good.
The best way to update other database tables is to perform the necessary get and save operations. However, if you have a many-to-many relationship, by default, both sides of the relationship are accessible from a <lower_case_model_name>_set parameter. That is, user.group_set.all() will give you all Group objects associated with a user, while group.user_set.all() will give you all User objects associated with a group. So if you override the save method (or register a signal listener--whichever option sounds stylistically more pleasing), try:
for group in user.group_set.all():
#play with group object
....
group.save()

Categories