when i update/edit data is duplicated instead of being updated in django - python-3.x

data is duplicated instead of being updated in django, please help me to overcome this i also tried update method but issues i have faced is image not displayed, therefore i is used save method which will save and make copy of anthor object which i dont want. it should update the same object.
views.py
def EuAdmin(request, pk):
pi = EmailDb.objects.get(id=pk)
if request.method == 'POST':
institution = request.POST.get('institution', '')
fullname = request.POST.get('fullname', '')
email = request.POST.get('email', '')
contact = request.POST.get('contact', '')
position = request.POST.get('position', '')
uploadd = request.FILES.get('upload', '')
sdata = EmailDb(institution=institution, fullname=fullname, contact=contact, email=email, position=position, uploaddata=uploadd)
sdata.save()
return HttpResponseRedirect("/eadmin")
return render(request, 'NEC/eupdate.html', {'pi': pi})
models.py
class EmailDb(models.Model):
institution = models.CharField(max_length=300, blank=True, null=True)
fullname = models.CharField(max_length=50, blank=True, null=True)
contact = models.IntegerField()
email = models.CharField(max_length=300, blank=True, null=True)
position = models.CharField(max_length=100, blank=True, null=True)
uploaddata = models.FileField(upload_to='appointment_letter')
def __str__(self):
return self.fullname

That's because you create a new EmailDb object. You can edit the one with:
from django.shortcuts import get_object_or_404
def EuAdmin(request, pk):
pi = get_object_or_404(EmailDb, pk=pk)
if request.method == 'POST':
institution = request.POST.get('institution', '')
fullname = request.POST.get('fullname', '')
email = request.POST.get('email', '')
contact = request.POST.get('contact', '')
position = request.POST.get('position', '')
uploaded = request.FILES.get('upload', '')
pi.institution = institution
pi.fullname = fullname
pi.contact = contact
pi.email = email
pi.position = position
pi.uploaddata = uploaded
pi.save()
return HttpResponseRedirect('/eadmin')
return render(request, 'NEC/eupdate.html', {'pi': pi})
Note: It is better to use a Form [Django-doc]
than to perform manual validation and cleaning of the data. A Form will not
only simplify rendering a form in HTML, but it also makes it more convenient
to validate the input, and clean the data to a more convenient type.
Note: Models normally have no Db suffix. A model is not a table, it is stored in a relational database as a table, but even then it has extra logic like validators, managers, etc.
Note: Please use an EmailField [Django-doc] instead of a CharField [Django-doc] to store an email address, this can do validation to check if the entered data is indeed an email address.
Note: It is often better to use get_object_or_404(…) [Django-doc],
then to use .get(…) [Django-doc] directly. In case the object does not exists,
for example because the user altered the URL themselves, the get_object_or_404(…) will result in returning a HTTP 404 Not Found response, whereas using
.get(…) will result in a HTTP 500 Server Error.

sdata = EmailDb(institution=institution, fullname=fullname, contact=contact, email=email, position=position, uploaddata=uploadd)
sdata.save()
This performs an INSERT SQL statement.
Since you already have object just set the value and call save() as
def EuAdmin(request, pk):
pi = EmailDb.objects.get(id=pk)
if request.method == 'POST':
institution = request.POST.get('institution', '')
fullname = request.POST.get('fullname', '')
email = request.POST.get('email', '')
contact = request.POST.get('contact', '')
position = request.POST.get('position', '')
uploaded = request.FILES.get('upload', '')
pi.institution = institution
pi.fullname = fullname
pi.contact = contact
pi.email = email
pi.position = position
pi.uploaddata = uploaded
pi.save()
return HttpResponseRedirect("/eadmin")
return render(request, 'NEC/eupdate.html', {'pi': pi})

Related

How can i limit the number of objects we can save by with a condition and without a condition in django?

What is meant is, I want to save only one object with is_featured field true, if user tried to save another object with is_featured field true it needs to give a prompt, How can i accomplish that in django any idea?
class Event(BaseModel):
title = models.CharField(max_length=200)
time = models.TimeField()
date = models.DateField()
location = models.CharField(max_length=200)
location_url = models.URLField()
description = models.TextField()
is_featured = models.BooleanField(default=False)
image = VersatileImageField('Image', upload_to="web/events")
class Meta:
db_table = 'web_event'
verbose_name = ('Event')
verbose_name_plural = ('Event')
ordering = ('auto_id',)
def __str__(self):
return str(self.title)
You can add a check that if event is already created with is_featured true then you can return error else you can create instance
if Event.objects.filter(is_featured=True).exists():
return Response({"error":"Featured Event Already Exists"})
else:
Event.objects.create(**data)
```

how do I add to a JSON field in Django

AIM --- I am using Django to make a mock trading website for a project. I am running into problems trying to keep track of stocks a person owns. The problem is if someone buys 4 TSLA stocks and then 4 again it should be treated as 8 stocks of TSLA out of which they can sell 7 if they want. (BTW, I am using postgresql)
Problem --- Turns out this is very difficult to do, I couldn't find anything that would help me keep track of the stocks a person owns. so, I read and read and finally turned to JSON fields. but, I am running into an issue there are well when I do
u.stocks_owned = {f"{ticker}" : f"{stocks_bought_here}"}
u.save()
it works, it adds a key-value pair with the ticker and a number, but I don't know how to create a new row using this, or if someone already owns some stock of a company then how do I add to that??
Conclusion --- I don't need to to write code for me, just point me in the right direction I will figure it out myself!
User Model -
class User_Info(models.Model):
user = models.OneToOneField(User, null=True, related_name='info', on_delete = models.CASCADE)
username = models.CharField(max_length=200, null=True)
name = models.CharField(max_length=200, null=True, blank = True)
phone = models.CharField(max_length=200, null=True, blank = True)
email = models.CharField(max_length=200, null=True)
date_created = models.DateTimeField(auto_now_add=True, null=True)
balance = models.FloatField(null = True)
virtual_money_bought = models.BigIntegerField(null=True)
stocks_owned = models.JSONField(null=True)
def __str__(self):
return self.username
the view I am using --
if new_balance >= 0 and balance_pre_trade >= latestPrice * stocks_bought_here :
Trade.objects.create(
ticker = ticker,
stocks_bought = stocks_bought_here,
action = "Bought",
trader = user.info,
price_trade_at = latestPrice,
company_name = companyName,
balance_of_trader_after_purchase= new_balance
)
u = User_Info.objects.get(user = user)
u.balance = new_balance
u.stocks_owned = {f"{ticker}" : f"{stocks_bought_here}"}
u.save()
messages.success(request, f"You bought {stocks_bought_here} from {companyName} at a price of {latestPrice} ")
return redirect ("user")
else:
messages.error(request, "You dont have enough money in your account")

How to insert data to my DB when using another model's field in my form?

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.

How do I efficiency create big forms - FlaskForms

So I have an update form end point, which is very large, I've tried a few things to make it dynamically created to condense my code but I cant seem to figure it out.
#customers.route("/<int:customer_id>/update_customer", methods=['GET', 'POST'])
# not programmatic - needs work - I do not like this
def update_customer(customer_id):
post = Post.query.get_or_404(customer_id)
if post.author != current_user:
abort(403)
form = CustomerForm()
if form.validate_on_submit():
post.tpi_name = form.tpi_name.data
post.tpi_ref = form.tpi_ref.data
post.company_name = form.company_name.data
post.company_type = form.company_type.data
post.company_reg = form.company_reg.data
post.sic_code = form.sic_code.data
post.vat_number = form.vat_number.data
db.session.commit()
flash("That customer's record has been updated!", 'success')
return redirect(url_for('customers.view_customer', customer_id=post.id))
elif request.method == 'GET':
form.tpi_name.data = post.tpi_name
form.tpi_ref.data = post.tpi_ref
form.company_name.data = post.company_name
form.company_type.data = post.company_type
form.company_reg.data = post.company_reg
form.sic_code.data = post.sic_code
form.vat_number.data = post.vat_number
return render_template('customers/customers.html', form=form, username=current_user.username,image_file=current_user.image_file, email=current_user.email)
So say if we had 100+ fields in the form, how would I change this code so I don't have to explicitly state each field.
Based on pjcunningham's answer, and looking into wtform docs, I found this piece of code:
def edit_profile(request):
user = User.objects.get(pk=request.session['userid'])
form = EditProfileForm(request.POST, obj=user)
if request.POST and form.validate():
form.populate_obj(user)
user.save()
return redirect('/home')
return render_to_response('edit_profile.html', form=form)
Based on that, I guess you want to write this code:
if form.validate_on_submit():
form.populate_obj(post)
db.session.commit()
flash("That customer's record has been updated!", 'success')
return redirect(url_for('customers.view_customer', customer_id=post.id))
For the second part of your code (the "GET" branch), it depends on your intentions. You can populate your form with data from object when you create it:
form = CustomerForm(obj=post)

Django Haystack return related insances

Hi I´m using django with haystack search. I have one model for Events. Thats the model I'm doing the search on. I have a second model to count the hits/views for the Events. I wan't to return the number of hits for every event additional to the search results.
my view:
def event_search(request):
if request.method == 'POST':
query = str(request.POST['search'])
events = SearchQuerySet().auto_query(query).models(Event).order_by('date')
return render_to_response('event_search.html', {"events": events}, context_instance=RequestContext(request))
else:
return render_to_response('event_search.html', context_instance=RequestContext(request))
my models:
class Event(models.Model):
name = models.CharField(max_length = 70)
date = models.DateTimeField()
description = models.TextField()
active = models.BooleanField(default=True, editable=False)
featured = models.BooleanField(default=False)
class EventHitcount(models.Model):
hit = models.ForeignKey(Event)
ip = models.CharField(max_length=40)
session = models.CharField(max_length=40)
created = models.DateTimeField(default=datetime.datetime.now())
By giving the ForeignKey field a related name it can call and count the related objects.
class Foo(models.Model):
fk = models.ForeignKey(Event,related_name='foofk')
some more fields...
In the template:
{{ foo.foofk.count }}

Resources