How to insert data to my DB when using another model's field in my form? - python-3.x

I have two different models: Trainer and User. I'm pulling in the trainer_price field from Trainer into my form in User. Please note that I'm also not using a foreign key.
The problem I'm having is that the trainer_price is not getting inserted and the default value of 0 is there, which is not what I want.
The way the User form works is they fill out their name, address, email and the trainer_price is automatically populated once they selected a trainer. It's also a read-only field.
Here's what I've tried so far:
user views.py
def buyer(request):
user_form = UserForm()
trainer_listing = Trainer.objects.get(id=15).trainer_price
context = {'user_form':user_form, 'trainer_listing':trainer_listing}
if request.method == "POST":
user_form = UserForm(request.POST)
if user_form.is_valid():
user_form.save()
return redirect("/success_page")
return render(request, "user/user_form.html", context)
forms.py
class UserForm(forms.ModelForm):
Fullname = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'John Doe'}))
Email = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Email'}))
Mobile = forms.CharField(widget=forms.TextInput(attrs={'placeholder': '312-222-2222'}))
Address = forms.CharField(widget=forms.TextInput(attrs={'placeholder': '1234 Main St'}))
City = forms.CharField()
State = forms.ChoiceField(choices=STATES)
zipcode = forms.CharField()
trainer_price = forms.DecimalField(label="Trainer Price", required=False, widget=forms.TextInput(attrs={'readonly':'readonly'}))
class Meta:
model = User
fields = ['Fullname','Email', 'Mobile', 'Address', 'City',
'State', 'zipcode', 'trainer_price']
Any help in the right direction would be great!

Basically, we can set default values for the form field using the initial argument.
def buyer(request):
trainer = Trainer.objects.get(id=15)
user_form = UserForm(initial={"trainer_price": trainer.trainer_price})
# etc
PS. Make sure that you do not populate the value from the trainer_price with the results from the request.POST. Smart users could use this to get very cheap deals. In stead, always re-query the actual value.

Related

update a field in all records of a table through a single form Django 4

I have the following model 'ARTICULO', which I have created and templates to edit it individually
# MODEL
class Articulo(models.Model):
id = models.AutoField(primary_key=True, verbose_name='codigo')
nombre = models.CharField(max_length=100, verbose_name='nombre elemento')
cantidad = models.PositiveSmallIntegerField(verbose_name='cantidad total')
cantidad_disponible = models.PositiveSmallIntegerField(verbose_name='cantidad disponible', default=5)
UNIDAD = 'und'
KILO = 'kg'
LITRO = 'L'
UNIDADES_BASE = [
(UNIDAD, 'unidades'),
(KILO, 'Kilogramos'),
(LITRO, 'litros'),
]
unidades = models.CharField(max_length=3, choices=UNIDADES_BASE, default=UNIDAD, verbose_name='unidad base')
area = models.CharField(max_length=100, verbose_name='tipo inventario', default='primaria')
persona_asignada = models.CharField(max_length=100, default='almacen', verbose_name='persona asignada')
def __str__(self):
trama = "articulo: " + self.nombre
return trama
#form to edit individually
class ArticuloEditarForm(forms.ModelForm):
class Meta:
model = Articulo
fields = ['nombre', 'cantidad', 'unidades']
# view for generate form of individual article
def editar(request, id):
articulo = Articulo.objects.get(id=id)
formulario = ArticuloEditarForm(request.POST or None, instance=articulo)
if formulario.is_valid() and request.POST:
formulario.save()
return redirect('inventario_inicio')
return render(request, 'inventario/editar.html', {'formulario': formulario})
but additionally I would like to create a page where I can perform an update of all the records of the table as a whole (as in the following image)
When clicking on the button, all records with the checkbox activated are updated in the database according to the value indicated in their text box.
From what I have investigated so far, I think I understand that I should use the form.Form class and not form.ModelForm in combination with formsets, but in the attempts I have made, I tried trying to define a form in this way, but it does not work for me.
class AsignarReservasArticulos(forms.Form):
articulos = Articulo.objects.all()
for x in articulos:
print(x)
participa = forms.BooleanField(label='')
My deduction tells me that I must generate the form that I show in my image in an integral way from my FORM or I must make a part in the form and another in the view.

I want id with any one of the given details

Here is my models:
enter code here
class Room_Type(models.Model):
"""Django data model Room_Type"""
ROOM_CATEGORIES={
('Elt','Elite'),
('Lux','Luxury'),
('Sig','Signature')
}
image = models.ImageField(upload_to="pics")
roomtype = models.CharField(choices=ROOM_CATEGORIES,max_length=20)
price = models.CharField(blank=True, max_length=100)
def __str__(self):
return f'{self.roomtype}
I want Id with any one of the detail given in model,Help me solve geeks
when you create a model id is automatically created in django if you want to access that id you can access like this in your view
room_type = Room_Type.objects.get(name='John')
print(room_type.id)

How to show select field with pre-selected data using django forms?

I've a django Form with 2 choices (yes and no), on my "create page" i can render the select field to save the data and it works just fine, when i try to use on the "edit page" the value is not pre-selected with the current value, how can i make the current value selected on the select input field?
The form:
class MyForm(forms.ModelForm):
choose = forms.BooleanField(
required=False,
widget=forms.Select(
choices=[(1, 'Yes'), (0, 'No')],
attrs={'class': 'form-control'}
)
)
class Meta:
model = MyModel
When i call the view to edit:
class MyUpdateView(
LoginRequiredMixin,
SuccessMessageMixin,
UpdateView,
):
model = MyModel
form_class = MyForm
template_name = "my/template.html"
success_url = reverse_lazy('my-url')
success_message = 'Updated!'
def get_object(self, queryset=None):
data = super(MyUpdateView, self).get_object()
if not data.user == self.request.user:
raise Http404
# data.choose is False
return data
The HTML input will be always "1" (Yes) even tough the current value is "0" (No)
The HTML:
{{ form.choose }}
The Model:
class MyModel(models.Model):
choose = models.BooleanField(
default=False,
verbose_name='Cumulativo'
)
add this to your MyUpdateView:
initial = { 'choose': 1 }
You are defining the custom field 'choose' in the form, which does not refer to MyModel field 'choose'. that's why you are always getting the first value 'Y' as default or the first value 'Y' in the dropdown.
If you want to refer to your model object, you can simply use self keyword in the form
class MyForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
self.fields['choose'].widget.attrs['class'] = 'form-control'
class Meta:
model = MyModel
fields = ('__all__')

How to access model field value before edit form presented to user in flask-admin?

I have model User:
class User(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(50), unique=True, nullable=False)
token_life_time = db.Column(db.Integer, nullable=False)
and ModelView for it from flask-admin:
class UserModelView(ModelView):
column_list = ('id', 'username', 'token_life_time')
form_create_rules = ('username', 'token_life_span') # custom field, that doesn't exist in actual model
form_edit_rules = ('username', 'token_life_time', 'new_token_life_time')
form_extra_fields = {
'token_life_span': StringField(default='1-0-0-0', validators=[DataRequired()]),
'new_token_life_time': StringField() # how to put here actual value from model.token_life_time as default value in EDIT form ???
}
column_formatters = dict(
token_life_time=lambda v, c, m, p: UserModelView.convert_seconds_to_human_readable(m.token_life_time)
)
def on_model_change(self, form, model, is_created):
token_time = form.data.get('token_life_span', None)
if token_time:
model.token_life_time = self.convert_to_seconds(token_time) # my custom function that converts string of format (days-hours-minutes-seconds, example: 1-8-23-15) into seconds for storing in DB int type
I want to access model.token_life_time value before EDIT form presented to user and convert it from seconds to human readable string (with days, hours etc.). Then to put converted value as default value in custom field in edit form (new_token_life_time).
The question is - how to access actual value from model and then put converted value to custom field as default value in EDIT form ???
Override the view's edit_form method - see documentation.
Something like the following:
class UserModelView(ModelView):
def edit_form(self, obj=None):
form = super().edit_form(obj=obj)
# calculate token_life_span
_token_life_span = get_token_life_span(obj.token_life_time)
form.token_life_span.data = _token_life_span
return form

Flask Sample webpage that request input from user performs no action

I trying to learn how to code in Flask and am building a small portal that accepts inputs from the user (User could select among various check boxes). Based on the input I am trying to display the selected columns by means of an excel file. Given below what I have done thus far and I am not sure how to take this forward.
#app.route('/index', methods=['GET','POST'])
def user_input():
form = SampleForm()
if form.validate_on_submit():
Username = form.username_field.data
Age = form.age_field.data
output = user_input(Username,Age)
return render_template('index', form=form)
I have managed to build the above code by reading through various blogs and posts but this does nothing. Could anyone guide me on where am I going wrong with the above sample piece of code. Thanks
Class.py
class test(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(100), nullable=False)
age = db.Column(db.String(100), nullable=False)
Python function:
def function(*field_names):
cursor = conn.cursor()
dwh_cursor.execute('select {} from enrolments'.format(', '.join(str(field) for field in field_names)))
print(field_names)
output_file = dwh_cursor.fetchall()
Does this help? Might need some tweaking to fit your needs.
#app.route('/index', methods=['GET','POST'])
def user_input():
form = SampleForm()
if form.validate_on_submit():
newform = User(
username = form.username_field.data,
age = form.age_field.data,
)
db.session.add(newform)
db.session.commit()
return redirect(url_for('user_input'))
return render_template('user_input', form = form)

Resources