django forms doubt - django

Here, I am a bit confused with forms in Django. I have information for the form(a poll i.e the poll question and options) coming from some db_table - table1 or say class1 in models. Now the vote from this poll is to be captured which is another model say class2. So, I am just getting confused with the whole flow of forms, here i think. How will the data be captured into the class2 table?
I was trying something like this.
def blah1()
get_data_from_db_table_1()
x = blah2Form()
render_to_response(blah.html,{...})

Forms have nothing to do with models in Django. They are just class meant to get informations from a dictionary (often request.POST) and check if each data linked to a key match a type and a format (e.g: is this a string of the form "bla#foo.tld").
You can ask django to create a form from a model, and in that case it will do its checking job, then if the data match, it will create a model, fill it and save it.
If a form is not created from a model, it will do nothing but checking. It will save nothing.
If it is created from a model, it will create a new instance of this particular model instance and save it.
If you want something more complicated, like, pre fill a form from various models or according to some conditions, or, say, you need to save several models according to the result of one form, you must do it manually.

Related

Django - Using single list objects from a model class

So Create_Watchlist is a model with a Foreignkey to the User Model and 'ticker' is a CharField of Create_Watchlist. Here is my views.py function for the approach
def watchlist_one(request, pk):
Create_Watchlist.objects.get(id=pk)
list_ticker = list(Create_Watchlist.objects.all().values_list('ticker', flat=True))
At the moment list_ticker equals ['AAPL, BTC']
I want to access in this case 'AAPL' and 'BTC' as different list objects, because I want to make an API request with each list item. The list_ticker variable changes with the users input from a form . So there could be smt like ['AAPL, BTC'], but as well smt like ['FB'] (etc.)
If I've made a mistake here, an explanation of how to deal with query sets and data types would also help me!
Thanks a lot :)

Django: how store multiple data types to the same model field

I want to create a database model somewhat similar to the example below:
The idea is that User (or any model) can have multiple different features (or whatever) with different values. Feature can be anything, for example integer (salary), date (birthdate), or multiple selection (competences like C, Python, etc.). To keep the database design simple, I've tried an approach where I have only one Feature table which has optional choices via Choice table, instead of having separate database table for each feature type. User selection for feature value is stored to a User_has_Feature table "value" field, which is a CharField which can store multiple different data types, like integer, date, choice, multiple choice etc.
My question is, how can I validate all data so that it validates against the field data type, and also shows everything correctly in admin or UI (having different UI widgets for different types)?
I've tried an approach where I store the field type for each feature to Field table, which can be CharField, IntegerField, DateField, etc. Then in User_has_Feature model clean() I can dynamically validate against the field type, for example:
FIELDS = {
'DateField': DateField,
'IntegerField': IntegerField,
etc.
}
def clean(self):
class_ = FIELDS.get(self.feature.field)
if class_ in [DateField, IntegerField, ...]:
field = class_()
field.clean(self.value)
elif class_ in [ModelChoiceField, ModelMultipleChoiceField]:
etc.
This approach works fine for validation, but it isn't helping for admin widgets and also data is always handled as a string, instead of integer, date, list, etc. So I've started to investigate option to create a custom ValueField model field, which inherits CharField, and would store all the data as a string to the database, but would change the widget and data type (to_python) dynamically for the value. No success so far, everything I try seems to go overly complex.
For me this seems to be quite common need, thus I would expect that some "easy" solution already exist. Or then I need to try different approach with the database design altogether.
You can use Django Content Types Framework docs
The main idea is that you can create dedicated classes (models) to your features, and CTF could help you to link features to the User (in your case).
I'm using this for linking different models to the Logging model and each logging instance contains a direct link to the needed model instance that it logs.
UPDATE:
Ok, in Django terms we need:
Use ManyToMany for relation User<->Features. You can define this field as features in the user model. So it will be simple calling in the future, like: user.features.all(). Managing related features will be also simple.
Your clean method is correct: you are mapping string names of the str types of fields with classes. It's ok.
Use this trick to make the same mapping but on the admin's side forms
class OurModelAdmin(admin.ModelAdmin):
...
def formfield_for_dbfield(self, db_field, **kwargs):
if db_field.name == 'Multiple':
kwargs['widget'] = forms.CheckboxSelectMultiple
# mapping is here
return super(OurModelAdmin, self).formfield_for_dbfield(db_field,**kwargs)
...

Django ManyToMany Field in form - unnecessary database calls?

In a django form that has a manyToMany field - is there a database call to retrieve each object in the list when you're adding a new entry? Is this necessary/ wasteful?
For example:
class MyForm(ModelForm):
likes = forms.ModelMultipleChoiceField(queryset=Videos.objects.all())
....
the form is submitted with a list of project id's. within the clean() method likes becomes a list of Video objects. However you can do:
self.instance.likes.add() ...without ever having to get the objects.
...
is it wasteful that the objects are being retrieved first before updating the relationship? if not, why?
I would say that every time you save the form, it would be evaluating the queryset you passed it to check that each ID is within that queryset. if you wish to optimize the behavior, try subclassing ModelMultipleChoiceField and removing the checks/making them more streamlined.

how to find associated Django ModelForm given the Model

I have dozens of Models, each with ONE associated ModelForm (whose Meta.model refers to the Model in question).
E.g.
class FooModel(Model):
pass
class FooModelForm(ModelForm):
class Meta:
model = FooModel
# current approach using a classmethod
FooModelForm.insert_in_model() # does cls.Meta.model.form = cls
So, obviously, it's easy to find FooModel given FooModelForm. What I want is to know the best way to do the REVERSE: find FooModelForm when I am presented with FooModel or even the string "Foo".
Assume only one ModelForm for each model, although solutions that return multiple are fine.
My current approach is to stash the model in the form class (as shown above), but I'm interested in knowing better approaches especially ones that could compute it centrally (without the final line above).
EDIT: I've reviewed things like Django: Display Generic ModelForm or predefined form but I believe this is a simpler question than those. The Django admin code must do something along the lines of what I seek. But get_model equivalent for ModelForms? suggests that might be voodoo and that it would be best to just do dict['Foo']=FooModelForm or its equivalent to keep track of the association explicitly. Seems repetitious.
If you have under 20 forms, sounds like mapping out a dictionary is the easiest way. Django does this kinda thing internally too.
For ModelForms, django admin just creates them on the fly via modelform_factory, so there is no comparable method to get_model
I do see, your method is bullet proof, but requires a line in ever model def.
If you only have one ModelForm per model, you could potentially iterate through the ModelForm subclasses until you find your form.
find FooModelForm when I am presented
with FooModel or even the string
"Foo".
modelforms = forms.ModelForm.__subclasses__()
def get_modelform(model):
try:
return filter(lambda x:x.Meta.model == model, modelforms)[0]
except IndexError:
print "apparently, there wasn't a ModelForm for your model"
If you want to pull the ModelForm as a string, you'll need to make sure both
app_label and __name__ are correct, which means it will be easier to use get_model('app', 'model') in the function.
You could combine this with your method and automatically place an attribute on your models that point to its ModelForm.
Hook into the class_prepared signal at the top of your apps, find the corresponding ModelForm and attach it to your Model class.
Hope that helps or gives you some ideas.

How do you modify the default widget for all builtin form fields of a certain type in Django?

This is a follow-up on How do you change the default widget for all Django date fields in a ModelForm?.
Suppose you have a very large number of models (e.g. A-ZZZ) that is growing with the input of other developers that are beyond your control, and you want to change the way all date fields are entered (i.e. by using jQueryUI). What's the best way to ensure that all date fields are filled out using that new widget?
One suggestion from the cited question was:
def make_custom_datefield(f):
if isinstance(f, models.DateField):
# return form field with your custom widget here...
else:
return f.formfield()
class SomeForm(forms.ModelForm):
formfield_callback = make_custom_datefield
class Meta:
# normal modelform stuff here...
However, is this possible to do where you don't have explicit ModelForm's, but url patterns come from models directly? i.e. your url config is likeso:
url(r'^A/?$', 'list_detail.object_list', SomeModelA)
where SomeModelA is a model (not a form) that's turned into a ModelForm by Django in the background.
At present in my system there are no Forms for each Model. The only point of creating forms explicitly would be to add the formfield_callback suggested in the prior solution, but that goes against DRY principles, and would be error prone and labour intensive.
I've considered (as suggested in the last thread) creating my own field that has a special widget and using that instead of the builtin. It's not so labour intensive, but it could be subject to errors (nothing a good grep couldn't fix, though).
Suggestions and thoughts are appreciated.
It sounds like you want to do this project-wide (ie: you're not trying to do this in some cases, but in ALL cases in your running application).
One possibility is to replace the widget attribute of the DateField class itself. You would need to do this in some central location... something that is guaranteed to be loaded by every running instance of the django app. Middleware can help with this. Otherwise, just put it in the __init__ file of your app.
What you want to do is re-assign the widget property for the forms.DateField class itself. When a new DateField is created, Django checks to see if the code specifies any particular widget in the field property definition. If not, it uses the default for DateField. I'm assuming that if a user in your scenario really defined a particular widget, you'd want to honour that despite the change to your global API.
Try this as an example of forcing the default to some other widget... in this case a HiddenInput:
from django import forms
forms.DateField.widget = forms.HiddenInput
class Foo(forms.Form):
a = forms.DateField()
f = Foo()
print f.fields['a'].widget
# results in <django.forms.widgets.HiddenInput object at 0x16bd910>