Django admin store dynamic formset added with ajax - django

I'm currently implementing a solution using django admin, it allows users to define in the db a product, and then custom attributes and details, more details may be aggregated by a common attribute, this allows me to query with ajax a custom view that returns some JSON data to build automagically the form fields that I need directly in the same formset view (manipulating the DOM).
The current DB design follows this schema:
Catalog(name, description, photo)
Product(rel_catalog, name, base_price, photo, manufacturer_email)
ProductDetail(rel_product, rel_attribute, percentage_price, fixed_price)
ProductAttribute(rel_product, name, description)
As you may see I have a catalog, where there can be more products, a lot of details per product, aggregated by attributes. Then I simple show by default the Catalog, then the select with all available products for that catalog, then, choosing the right Product, I obtain the complete form (each row has a label with ProductAttribute.name and a select with related ProductDetail).
All works pretty dam good, but I also need to store this references in the DB when someone completes the form (making an order with choosen products). This forms are displayed as StackedInline (the ModelAdmin is for the Order).
I don't know how many options there may be per product so I was thinking to use this design to track orders:
Order(customer, status, notes, tot_price, inserted_by)
OrderItem(rel_order, catalog, product, unit_price)
But I don't know how to store the dynamic added inputs...
I was thiking to implement OrderItemProperty(rel_orderitem, rel_productdetail, rel_productattribute) to store each single input... but how do I loop over this unknown fields?
Maybe do you suggest a better design?
If you need more code just ask for it and I'll reply with a pastebin link.
Thankyou.

Finally I got a working solution,
I've created a custom view, overriding the default "add/" view, this way I can customize whatever I want to and I can read the POST data handling each validation, putting then the data in the right model.

Related

User generated item multiple choice field Django

I am looking for a way to have a multiple choice field populated with choices made by a user. For example, they could have the following 3 entries: Yes, No, Unsure. I want a way to be translate this to a model.
I understand this can be done with pre-defined options using a CharField, or ChoiceField, but I haven't seen anything with "dynamic" data, such as user-generated data.
I think you shouldn't use choice fields in this case, because everytime a user creates a new option, you'll have to run a new migration.
Maybe you can create a UserOption model and create a new obj everytime a user creates a new option. Then fetch all the options the user has created when he needs to choose between them.
You can't apply user choices to a DB table. However, you could store a user's choices somewhere, such as a User's Profile, and use them in a dynamically constructed form with a ChoiceField to constrain what he can put into a particular database column / model field.
Could be a PITA if he decides to delete a choice and then wants to edit the (now invalid) data in one of his records.

Best practice for using Django templates and connect it to database

I am trying to build a database for my website. There are currently three entries with different attributes in my database. I have not created these entries in order, but I have assigned a 'Chapter number' attribute which indicates the order 1,2,3.
I am now trying to inject this using 'context' and 'render' function in my views. I am using the method 'objects.all()' to add all objects to my context. I have a simple Html file where I am inserting the data from the database by looping over (a simple for loop) these added objects.
Now the output that is being generated (naturally) is that it is following the order in which I created the database. I am not sure how I can have the loop run in such a way that I get these chapters in correct order. Thank you for patiently reading my question. Any help will be appreciated.
You may use the order_by method which is included in Djangos QuerySet API:
https://docs.djangoproject.com/en/3.0/ref/models/querysets/
If you offer some more information of your specific data I might provide you with an example.
For orientation purposes, sorting queried objects by date would work as follows:
most_recent = Entry.objects.order_by('-timestamp')
You can sort by any field like so:
sorted_by_field = Entry.objects.order_by('custom_field')

Creating a new table on the fly

I am new to Django plotform. I am trying to write a program which basically accepts a post method. The content of incoming data is storename, bookname, bookserial. That part is already implemented and works well. When I post the content such as storename=John's shopping center, bookname=Love is beatiful, bookserial=123. It creates a table and save those things into a table. But, the thing is that I want to create not just only one table for each store. Because, I can have multiple storename and each store should have its own table. When I post the storename on the fly ,it should check storename and then if it's table is created already, the bookname and bookserial should be inserted its table. If not, a new table should be created and then the incoming data is inserted the new table. The new table name should be storename as well.So, as I said, I only need to learn how to create new tables on the fly part. Could you please help me how to do that, any comments and ideas is appreciated....
An example to make it clear,
Table-1=John's shopping center
bookname=Love is beatiful
bookserial=123
Table-2= John's shopping center-2
bookname=Time is important
bookserial=456
So, the model is same for each shopping center but each of sopping center is a different table with the name of shopping center.
In the traditional sense, it is not possible to dynamically create concrete tables on the fly in django. Models have to be registered as part of the application startup, so that the ORM can properly manage all the relations. Consider what would happen if you defined a new model that set up constraints or backrefs to other models. Those other models, being classes, have already been set up and are in memory. They can no longer go through their metaclass step to wire new relations. You could easily break things.
Your options are limited to either a solution involving a few tables that can dynamicaly describe different entities, or to use a nosql backend that does not care about schemas and will let you store anything at any time.
See this question and answer for details: Django dynamic model fields
The only way to have a concrete table on the fly is if you have the django app restart itself completely in response.

Django Form 2 Stages

I'm trying to make a Django order system that requires 2 forms. The first form, lets users choose some some quantities and basic contact info some. Then, using the quantities of each item they ordered I generate a 2nd form which allows them to choose some options for each item. This system is specifically for event tickets. Here are the 2 stages:
1) Get the order info such as name, address, phone of the person placing the order. Also find out how many people are coming to each of the possible events.
2) Based on the number of people per event, get their name and e-mail address.
I already have both forms created. I am just getting tripped up in the views. When they submit form 1, I need to take that info and save some of it and then send them to form 2. At form 2, they will fill out the rest of the info and finish processing.
How would you set up the views in such as case? I essentially nee-d to call on view form another and pass data between. I tried using kwargs, but I have trouble processing the second form.
Without seeing your models, it's hard to give an exact solution, but one approach is to have two separate views, one for each form.
Once you've processed the first form, you're most likely going to have an instance of some object that you created from the first form. It sounds like you just need to pass the id of that object to your next view where you could then get that object and do whatever association you need.
Also, it sounds like you might need to be collecting data from several instances of a form...
(2) Based on the number of people per event, get their name and e-mail
address.)
You'll want to use a formset for that.

Seeking Good Approach to Persist Data Submitted Through Dynamic Django Forms

Summary:
Looking for a good way to save data to Django models for which the associated forms are generated dynamically.
Detail:
I've been puzzling over the best approach for creating dynamic Django forms backed by models. For example, I'd like to create an interface where a user can create an HTML form, customize the types of fields in that form dynamically (Number, String, Dropdown Box, Date, etc.), and then display that form to other users so those users can submit data which is saved to a database. I'm not sure how to make an efficient approach to persist the data.
www.formsite.com and www.mailchimp.com have some form-building tools that are nice examples of what I am trying to do. Jacob Kaplan-Moss has an excellent tutorial on how to create the forms dynamically, but the tutorial doesn't get into how to persist the data.
As a dummy example, one (perhaps bad?) approach might be to create some models like below, where there is a database table for the SurveyQuestions (storing the customizable names and datatypes of each field) and one for the SurveyQuestionResponses (each record storing an individual response for a SurveyQuestion on a particular Survey).
However, it seems like this approach might result in really complex and slow queries. For example, if a Survey has 10 questions and you would like to display 10 user responses to that survey, there would be queries to select all 10 SurveyQuestions and then for each survey responder, there would be a query to select each of the SurveyQuestionResponses. It seems like the number of queries needed could add up really fast!
class Survey(models.Model):
# some fields here.
pass
class SurveyQuestion(models.Model):
""" Defines the headings and field
types for a given Survey.
"""
survey = models.ForeignKey(Survey)
field_name = models.CharField(
max_length=255,
help_text='Enter the name for this field heading')
field_type = models.IntegerField(
choices=choices.FIELD_TYPES,
help_text='Enter the data type for this field')
display_order = models.IntegerField(default=0)
class SurveyQuestionResponse(models.Model):
survey_field = models.ForeignKey(SurveyQuestion)
response value = models.TextArea(blank=True, null=True)
Is there a better approach to persisting data based on dynamic forms? Should I be somehow converting a form respondent's response to some sort of pickled format and store it to a TextField (Instead of having 10 SurveyQuestionResponse records there would be one record with all the response values pickled together)? I'm not too familiar with NoSQL options, but would a NoSQL approach work best for this type of thing? Is there some sort of rendering or caching that would make sense to do?
I keep encountering situations where saving data from dynamic forms like this would be very useful. I am wondering what other people's approaches are. Any advice is much appreciated. Thanks for reading this admittedly long question.
Joe
For a relational database an Entity-attribute-value model(EAV) could be used to achieve a dynamic, or open schema. Relational databases are not really suited for this type of schema, and this generally results in very slow queries over time. NoSQL has its own set of issues but I think that it would be best suited to your requirements. If you decide to take this route you can take a look at MongoDB. I have not used it extensively, but it seems most similar to relational database than the other NoSQL database out there, and its python interface seems pretty similar to django's ORM. By the was I remember finding a nice EAV example for Django. Though I don't remember where at the moment.