Post method in Django models - python

I am new in Django forms and I need to insert/update some data into my database.
I have some model and in the django admin panel I introduce manually the user's phone and the IMEI number.
After that I create a form, a template.html and a view.
The form is as follows:
from django import forms
class Send2phone(forms.Form):
NumberOfCalls = forms.CharField(
min_length=1,
widget=forms.TextInput({'class': 'form-control'})
)
TimeBetweenCalls = forms.CharField(
widget=forms.TextInput({'class': 'form-control'})
)
PSAP = forms.CharField(
min_length=1,
widget=forms.TextInput({'class': 'form-control'})
)
And my view is:
def phone_config(request):
if request.method == 'POST':
form = Send2phone(request.POST)
if form.is_valid():
cleaned_data = form.cleaned_data
NumberOfCalls = cleaned_data.get('NumberOfCalls')
TimeBetweenCalls = cleaned_data.get('TimeBetweenCalls')
PSAP = cleaned_data.get('PSAP')
phone_model = Phone()
phone_model.id = 1
phone_model.user = donothing
phone_model.imei = donothing
phone_model.num_calls = NumberOfCalls
phone_model.time_btwn_calls = TimeBetweenCalls
phone_model.psap = PSAP
phone_model.save()
return redirect(reverse('gracias'))
else:
form = Send2phone()
return render(request, 'heroconfigurer/heroconfigurer.html', {'form': form})
def gracias_view(request):
return render(request, 'heroconfigurer/gracias.html')
My problem comes now when I create the view. First of all, I check if the method is post and I get the data from the form.
Then I check if the form is valid and I create the object Phone. After that assign the different parameters and save them.
Inserting the data from the form is working good but imei and user ara being deleted if I don't specify them.
How can I insert data in the database models where exist some users and imeis? For example in id=1 I already have a user and an imei and I want to keep them

Existing fields are erased because you're creating new Phone object with existing id. You should instead retrieve existing Phone model and update it:
phone_model = Phone.objects.get(id=1)
phone_model.num_calls = NumberOfCalls
phone_model.time_btwn_calls = TimeBetweenCalls
phone_model.psap = PSAP
phone_model.save()
Or update it using queryset update method:
Phone.objects.filter(id=1).update(
num_calls=NumberOfCalls,
time_btwn_calls=TimeBetweenCalls,
psap=PSAP,
)
First one will touch database twice. Once for loading existing phone, and then for saving new values. Second will touch database only once, updating fields without touching rest of them.

You should be retrieving the existing Phone object and updating it where necessary.
if form.is_valid():
number_of_calls = form.cleaned_data.get('NumberOfCalls')
time_between_calls = form.cleaned_data.get('TimeBetweenCalls')
psap = form.cleaned_data.get('PSAP')
phone = Phone.objects.get(pk=1)
phone.num_calls = number_of_calls
phone.time_btwn_calls = time_between_calls
phone.psap = psap
phone.save()
Even better, make your form a ModelForm, and include only the fields you want to update:
class Send2phone(forms.ModelForm):
class Meta:
model = Phone
fields = ['num_calls', 'time_btwn_calls', 'psap']
now your view is just:
phone = Phone.objects.get(pk=1)
if request.method == 'POST':
form = Send2tcu(request.POST, instance=phone)
if form.is_valid():
form.save()
return redirect(reverse('gracias'))
else:
form = Send2tcu(instance=phone)
return render(request, 'heroconfigurer/heroconfigurer.html', {'form': form})

Related

How To Update Specific Model Field From Django View Before Saving A Form

So, How can I update some Model Fields automatic, without the user having to input the values?
In Models:
class Url(models.Model):
long_url = models.CharField("Long Url",max_length=600)
short_url = models.CharField("Short Url",max_length=7)
visits = models.IntegerField("Site Visits",null=True)
creator = models.ForeignKey(CurtItUser,on_delete=models.CASCADE,null=True)
def __str__(self):
return self.short_url
In Views:
def home(request):
"""Main Page, Random Code Gen, Appendage Of New Data To The DB"""
global res,final_url
if request.method == 'POST':
form = UrlForm(request.POST)
if form.is_valid():
res = "".join(random.choices(string.ascii_uppercase,k=7))
final_url = f"127.0.0.1:8000/link/{res}"
form.save()
redirect(...)
else:
form = UrlForm
return render(...)
Sow how can for exapmle set from my view the value of short_url to final_url ???
You can get the data you need from the form.
you need to get the specific instance first, then you can use that instance to save values from the form.
And do not forget to save!
url_instance = get_object_or_404(Url, pk=pk)
url_instance.short_url = form.cleaned_data['short_url']
url_instance.long_url = form.cleaned_data['long_url']
url_instance.visits = form.cleaned_data['visits']
url_instance.save()
You can find more detailed infromations in the Django Documentation.

associate the user with the post Django and MySQL

I am trying to associate the user with the post. I have two models students is for user and sublists is for user posts with a foreign key(author). I am using MySQL database and using forms to store data into them. when my form.author execute in my HTML file it gives me a list of ids for all users in the databse but I am already logged in and i want to post as the logged in user without choosing. If remove it says my form is not valid which make sense since im not inputing for form.author.Since I'm using MySQL, I'm not using the built-in User authentication method, but instead comparing both email and password with the login form input. Spend too much time on this but hard to get around with this one. Any help would be appreciated
my views.py look like this
def addnew(request):
if request.method == 'POST':
form = Sublist(request.POST)
if form.is_valid():
try:
form.save()
messages.success(request, ' Subscirption Saved')
name = sublist.objects.get(name=name)
return render (request, 'subscrap/main.html', {'sublist': name})
except:
pass
else:
messages.success(request, 'Error')
pass
else:
form = Sublist()
return render(request, 'subscrap/addnew.html', {'form': form})
#login_required(login_url='login')
#cache_control(no_cache=True, must_revalidate=True, no_store=True)
def main(request):
return render(request, 'subscrap/main.html')
def mod(request):
student = students.objects.all()
return render(request, 'subscrap/mod.html' , {'students': student})
My Models.py
class students(models.Model):
fname = models.CharField(max_length=50)
lname = models.CharField(max_length=50)
password = models.CharField(max_length = 50 , null = True)
passwordrepeat = models.CharField(max_length = 50, null = True)
email = models.EmailField(max_length=150)
class Meta:
db_table = "students"
class sublist(models.Model):
author = models.ForeignKey(students, related_name='sublist' ,on_delete=models.CASCADE)
name = models.CharField(max_length=150)
cost = models.IntegerField(default = 0)
renewalcycle = models.IntegerField(default = 0)
class Meta:
db_table = "sublist"
Since I'm using forms here's my forms.py
lass StudentForm(forms.ModelForm):
class Meta:
model = students
fields = "__all__"
class Studentlogin(forms.Form):
email = forms.EmailField(max_length=150)
password = forms.CharField(max_length = 50, widget=forms.PasswordInput)
class Sublist(forms.ModelForm):
class Meta:
model = sublist
fields = "__all__"
Exclude the Author from the Sublist form:
class Sublist(forms.ModelForm):
class Meta:
model = sublist
exclude = ['author']
In the addnew method, you associate the .instance.author with the request.user:
#login_required(login_url='login')
def addnew(request):
if request.method == 'POST':
form = Sublist(request.POST)
if form.is_valid():
form.instance.author = request.user
form.save()
messages.success(request, ' Subscirption Saved')
return redirect('some_view')
else:
messages.error(request, 'Error')
else:
form = Sublist()
return render(request, 'subscrap/addnew.html', {'form': form})
Note: Models in Django are written in PascalCase, not snake_case,
so you might want to rename the model from sublist to Sublist.
Note: Usually a Form or a ModelForm ends with a …Form suffix,
to avoid collisions with the name of the model, and to make it clear that we are
working with a form. Therefore it might be better to use SublistForm instead of
Sublist.
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the students directly. For more information you can see the referencing the User model section of the documentation.

Setting an initial value in a Django Form

I have to setup an initial value in a form and somehow is not working, it is extremely strange as I have exactly the same code in another view, but in this case my approach is not working:
views.py
#login_required
def add_lead(request):
if request.method == 'POST':
lead_form = LeadsForm(request.POST)
if lead_form.is_valid():
lead_form.save()
messages.success(request, 'You have successfully added a new lead')
return HttpResponseRedirect(reverse('add_lead'))
else:
messages.error(request, 'Error updating your Form')
else:
user = {"agent":request.user}
lead_form = LeadsForm(request.POST or None, initial = user)
return render(request,
'account/add_lead.html',
{'lead_form': lead_form}
)
forms.py
class LeadsForm(forms.ModelForm):
class Meta:
model = Leads
fields = ('project_id','company','agent','point_of_contact','services','expected_licenses',
'expected_revenue','country', 'status', 'estimated_closing_date'
)
widgets = {'estimated_closing_date': DateInput(),
}
Essentially, the agent is the logged user, so I'm passing request.user as a variable, but I have not succeeded, which is very strange because I have that same logic in another form
Any help will be appreciated
If you want to make a form with a foreign key you can use ModelChoiceField. In your case you can use:
class LeadsForm(forms.ModelForm):
agent = forms.ModelChoiceField(queryset=User.objects.all())
class Meta:
model = Leads
fields = ('project_id','company','agent','point_of_contact','services','expected_licenses',
'expected_revenue','country', 'status', 'estimated_closing_date'
)
widgets = {'estimated_closing_date': DateInput(),
}
Then you can assign data with user_id in your form initial.

Django ModelForm: Defining a value not passed into the template

I have a ModelForm, and I want to only pass some of the fields into the template. I would like to save one particular field to define after the POST request has been sent. Here is the ModelForm:
class CreateListingForm(ModelForm):
class Meta:
model = models.ListingModel
fields = ['name', 'image', 'description', 'price', 'category']
widgets = {
'description': Textarea()
}
And here is the Model:
class ListingModel(models.Model):
name = models.CharField(max_length=30)
image = models.ImageField(upload_to='images')
description = models.CharField(max_length=1000)
price = models.PositiveIntegerField()
category = models.CharField(max_length=15)
objects = models.Manager()
owner = models.CharField(max_length=100)
In the next code block, I am attempting to define the owner field according to the current user logged in (request.user.username):
#login_required(redirect_field_name=login_view)
def create_listing(request):
if request.method == "GET":
return render(request, "auctions/createlisting.html", {
"CreateListingForm": forms.CreateListingForm()
})
elif request.method == "POST":
form = forms.CreateListingForm(request.POST, request.FILES)
if form.is_valid():
try:
form.owner = request.user.username
print(form.owner)
form.save(commit=True)
except Exception:
return HttpResponseRedirect(reverse("create_listing_error"))
return HttpResponseRedirect(reverse("index")) #TODO
Now, when I say print(form.owner), the result is correct. However when I save the ModelForm, the owner field is left blank. Am I not defining the value of the owner field correctly?
You should not confuse the ModelForm with the instance it is wrapping. The fact that it prints something for form.owner is not that strange, you first set an attribute named .owner, an attribute that did not exists before. You should set the .owner of the .instance of the form:
#login_required(redirect_field_name=login_view)
def create_listing(request):
if request.method == 'POST':
form = forms.CreateListingForm(request.POST, request.FILES)
if form.is_valid():
form.instance.owner = request.user.username
form.save()
return redirect('name-of-some-view')
else:
form = forms.CreateListingForm()
return render(request, 'auctions/createlisting.html', {
'CreateListingForm': form
})
Where 'name-of-some-view' should be replaced by the name of some view to which you redirect in case the form was valid.
You should however consider changing the CharField of owner to a ForeignKey [Django-doc]. Imagine that later the user changes their username, then your ListingModels do no longer refer to a real user.

Django using a modelform to update an instance of model

I have the following model in Django which I use to store data about medicines.
class Medicine(models.Model):
Medicine_Name = models.CharField(max_length=100)
User_Associated = models.ForeignKey(User, on_delete=models.CASCADE)
Tablets_In_Box = models.IntegerField()
Dose_in_mg = models.IntegerField()
Dose_Tablets = models.IntegerField()
Number_Of_Boxes = models.IntegerField()
Last_Collected = models.DateField()
def __str__(self):
return self.Medicine_Name
def get_absolute_url(self):
return reverse('tracker-home')
I am trying to create a model form where a user can update the last collection of one of their medicines. Here is what I began with.
class CollectionForm(forms.ModelForm):
class Meta:
model = Medicine
fields = ['Medicine_Name', 'Number_Of_Boxes', 'Last_Collected']
I do not understand how I can call an instance of my model based on the 'Medicine_Name' from the field. In other words, I need the user to be able to select the correct medicine from a dropdown menu, and then the form must update the 'Last_Collected', and 'Numer_Of_Boxes' fields on my Medicine model.
https://docs.djangoproject.com/en/2.1/topics/forms/modelforms/#the-save-method
It seems this contains relevant information, but I struggle to see how to use it in this instance. How can I correctly get the instance of the medicine form I need, based on the user input in the form? Furthermore how can I use the save method in my views to make sure the database gets updated correctly?
EDIT Added view for the form:
def update(request, pk):
instance = Medicine.objects.get(id=pk)
if request.method == 'POST':
form = CollectionForm(user=request.user, instance=instance, data=request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.User_Associated = request.user
instance.save()
else:
form = CollectionForm()
context = {'form': form}
return render(request, 'tracker/medicine_collection.html', context )
**EDIT
views:
def update(request, pk):
instance = Medicine.objects.get(id=pk)
if request.method == 'POST':
form = CollectionForm(instance=instance, data=request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.User_Associated = request.user
instance.save()
return redirect ('/')
....
This is based on updating the instance of the specific user. This tutorial helpt me achieve the same thing.
https://youtu.be/EX6Tt-ZW0so
Tried a different approach (class based views - UpdateView) I just learned here on SO. Did not test it but I think its a step in the right direction.
class UpdateMedicine(LoginRequiredMixin, UpdateView):
model = Medicine #call the model you need to update
fields = ['Medicine_Name', 'Number_Of_Boxes', 'Last_Collected'] #specify the fields you need to update
template_name_suffix = 'medicine_update_form' #specify the template where the update form is living
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update(
user=self.request.user, #get the current logged in user
instance=get_object_or_404(Medicine, pk=self.kwargs['pk']) #get the pk of the instance
)
return context
def form_valid(self, form):
form.instance.medicine = get_object_or_404(Medicine, slug=self.kwargs['pk'])
return super().form_valid(form) #saves the updates to the instance
def get_success_url(self):
return reverse('medicine-collection') #name of the url where your 'tracker/medicine_collection.html is living
Link the appropriate templates and urls to the above example and try some things yourself.
Link to the django docs:
https://docs.djangoproject.com/en/3.0/ref/class-based-views/generic-editing/
Good luck!

Categories