Django duplicate existing record in database - django

I'm trying to duplicate an existing record in a PostgreSQL DB, it seems to be duplicating by increments of 2 each time I hit the duplicate button. If there's 1 record in the database, once the button is hit it will create records 2 and 3.
Model
class Detail(models.Model):
created = models.DateTimeField(auto_now_add=True, blank=False)
last_update = models.DateTimeField(auto_now=True)
user = models.ForeignKey(User, related_name='+')
draft = models.BooleanField()
outage_name = models.ForeignKey(Outage, related_name='+')
group_name = models.CharField(max_length=100)
shift = models.CharField(max_length=6)
activity = models.CharField(max_length=100, null = False)
culture_title = models.ForeignKey(Culture, related_name='+')
work_completed = models.TextField()
work_planned = models.TextField()
radiation_info = models.TextField()
action_item = models.TextField()
lesson_learned = models.TextField()
View
def turnover_copy(request, id):
obj = Detail.objects.get(pk=id)
obj.pk = None
obj.draft = True
if obj.draft:
user = request.user.id
obj.user_id = user
obj.work_planned = 'My Work Planned.'
obj.save()
return HttpResponse('Created')
else:
return HttpResponse('Unable to duplicate template.')
EDIT: I had the def inside a for loop in the template, so it kept creating duplicates!

Are you sure the code isn't called twice for some reason? Some print statements might help you assert that.

Related

How to render a foreign key field in Django

Desired outcome: When I render a Poller and its associated comments
I would like to also render the Vote a user selected for the Poller along with his comment (Note: A user can only comment if he voted on that poller).
Side note: A user can make one vote to a Poller and post one comment to a Poller. He can only comment if he voted beforehand.
# Models
class Poller(models.Model):
poller_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
created_on = models.DateTimeField(auto_now_add=True)
created_by = models.ForeignKey(Account, on_delete=models.CASCADE)
poller_text = models.CharField(max_length=333)
poller_choice_one = models.CharField(max_length=20)
poller_choice_two = models.CharField(max_length=20)
class Vote(models.Model):
poller = models.ForeignKey(Poller, on_delete=models.CASCADE, related_name='vote')
user = models.ForeignKey(Account, on_delete=models.CASCADE)
created_on = models.DateTimeField(auto_now_add=True)
poller_choice_one_vote = models.BooleanField(default=False)
poller_choice_two_vote = models.BooleanField(default=False)
def __str__(self):
return f'Vote by {self.user}'
class Comment(models.Model):
poller = models.ForeignKey(Poller, on_delete=models.CASCADE, related_name='PollerComment')
user = models.ForeignKey(Account, on_delete=models.CASCADE)
created_on = models.DateTimeField(auto_now_add=True)
comment = models.TextField(max_length=350)
flag_count = models.IntegerField(default=0)
upvote_count = models.IntegerField(default=0)
downvote_count = models.IntegerField(default=0)
# View
#require_GET
def render_single_poller(request, poller_id):
# Retrieve comments associated to the Poller
comments_qs = PollerComment.objects.filter(poller_id=poller_id)
context = {
'comments_qs': comments_qs,
}
return render(request, 'pollboard/single_poller.html', context)
I tried to do it via a template filter like so:
# pollboard_tags.py
#register.filter(name='get_vote')
def get_voted(self):
self.vote_made = 'Test'
print(self.vote.poller_choice_one_vote)
if self.vote.poller_choice_one_vote:
self.vote_made = 'One'
else:
self.vote_made = 'Two'
return self.vote_made
# template
<div class="commentors-poller-choice">{{ comment|get_vote }}</div>
throws
RelatedObjectDoesNotExist at /poller/68c725eb-277e-4b5b-a61b-b4a02bf5e854/
PollerComment has no vote.
I fear that I'm already overcomplicating things here. I hope there is a more straightforward solution to this like idk expanding the comments queryset by the required information for rendering?
If a user can vote on a poller only once, you can filter with:
#register.filter(name='get_vote')
def get_voted(self):
vote = Vote.objects.get(poller=self.poller, user=self.user)
return 'One' if vote.poller_choice_one_vote else 'Two'

Model is not iterable in Django

I'm getting this error when I click on a button.
When I click the button I'm calling a function named apply.
So first of all, I've two models, JobServices and MissionEffectuee, the table MissionEffectuee is normally filled with content of JobServices.
The 2 models:
class JobServices(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True) #create_user
service_name = models.CharField(max_length=100, default="nom du service")
hour = models.IntegerField(default="Heures")
amount = models.FloatField(default="Cout")
service_date = models.DateTimeField(auto_now_add=True, null=True)
description = models.CharField(max_length=2000, null=True, default="annonce")
image_url = models.CharField(max_length=2000, null=True, blank=True)
image = models.ImageField(null=True, blank=True)
class MissionEffectuee(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
service = models.ForeignKey(JobServices, on_delete=models.CASCADE, null=True)
rcd_date = models.DateTimeField(auto_now_add=True, null=True)
Here is the views methods
def apply(request, my_id):
task_applied = JobServices.objects.get(id=my_id)
task_done, failed = MissionEffectuee.objects.get_or_create(id=my_id)
if failed:
for c in task_applied:
task_done.service = c.service_name
task_done.user = c.user
print("it's saved")
task_done.save()
else:
print("Element is already there")
return redirect('../taches')
context = {'task_done': task_done}
return render(request, 'task_apply.html', context)
What I want is whenever I click on the button, service_name of the model Jobservices and user of the model User to be saved in the table MissionEffectuee in the attributes service and user respectively, but as for now, in the table these two columns are filled with hypen (-). But the rcd_date attributes normally filled as I want.
I think the problem is with the foreignkeys
You're doing a get on your JobServices model which will return 1 instance of that model.
So you need to just use that 1 instance, like this;
task_applied = JobServices.objects.get(id=my_id)
task_done, failed = MissionEffectuee.objects.get_or_create(id=my_id)
if failed:
task_done.service = task_applied  # This must be a `JobServices` instance, not the name
task_done.user = task_applied.user
print("it's saved")
task_done.save()
If you used JobServices.objects.filter() then it'd return a queryset of objects from that table and you could iterate over that like you do with for c in task_applied.

Django - Last Updated By and Update Date not working

Hi I need someone's advice.
I created a form add organizations and a form to edit organizations. These are working fine.
However, I have Last Updated By and Update Date fields on the model - These are not picking up the datetime and user information when editing the organization.
views.py
#login_required()
def organization_edit(request, pk):
org = Organization.objects.get(org_id=pk)
form = OrganizationEditForm(instance=org)
# Update Org
if request.method == 'POST':
form = OrganizationEditForm(request.POST, instance=org)
if form.is_valid():
form.organization_code = form.cleaned_data['organization_code']
form.company_name = form.cleaned_data['company_name']
form.legal_name = form.cleaned_data['legal_name']
form.business_registration_no = form.cleaned_data['business_registration_no']
form.vat_registration_no = form.cleaned_data['vat_registration_no']
form.industry_distribution = form.cleaned_data['industry_distribution']
form.industry_education = form.cleaned_data['industry_education']
form.industry_healthcare = form.cleaned_data['industry_healthcare']
form.industry_manufacturing = form.cleaned_data['industry_manufacturing']
form.industry_retail = form.cleaned_data['industry_retail']
form.industry_services = form.cleaned_data['industry_services']
form.effective_start_date = form.cleaned_data['effective_start_date']
form.effective_end_date = form.cleaned_data['effective_end_date']
org = form.save(commit=False)
org.last_updated_by = request.user
org.save()
return redirect('organizations_settings')
context = {
'form':form,
'org':org,
}
return render(request, 'settings/edit_organization.html', context)
models.py
class Organization(models.Model):
org_id = models.CharField(primary_key=True, max_length=7, default=org_id_generate, editable=False)
organization_code = models.CharField(max_length=20)
company_name = models.CharField(verbose_name="Company Name", max_length=60)
legal_name = models.CharField(verbose_name="Legal Name", max_length=100)
industry_distribution = models.BooleanField(verbose_name="Distribution", default=False)
industry_education = models.BooleanField(verbose_name="Education", default=False)
industry_healthcare = models.BooleanField(verbose_name="Healthcare", default=False)
industry_manufacturing = models.BooleanField(verbose_name="Manufacturing", default=False)
industry_retail = models.BooleanField(verbose_name="Retail", default=False)
industry_services = models.BooleanField(verbose_name="Services", default=False)
business_registration_no = models.CharField(verbose_name="Business Registration Number", max_length=15, blank=True)
vat_registration_no = models.CharField(verbose_name="VAT Registration Number", max_length=15, blank=True)
created_date = models.DateTimeField(default=datetime.now)
created_by = models.ForeignKey(User, on_delete=models.DO_NOTHING, related_name="Created_By", verbose_name="Created By")
effective_start_date = models.DateField(auto_now_add=False)
effective_end_date = models.DateField(auto_now_add=False, blank=True, null=True)
update_date = models.DateTimeField(default=datetime.now)
last_updated_by = models.ForeignKey(User, on_delete=models.DO_NOTHING, related_name="Last_Updated_By", verbose_name="Last Updated By")
def __str__(self):
return self.company_name
Any help appreciated!
You might have mistaken on how default value works in this case.
Your updated_datefield is kind of working while creating the row for the first time because of the dynamic default value datetime.now(). But it won't be automatically updated automatically later on. For this use I'd advise you to use DateTimeField with auto_now_add and auto_now set to True respectfully:
created_date = models.DateTimeField(auto_now_add=True)
modified_date = models.DateTimeField(auto_now=True)
https://docs.djangoproject.com/en/3.1/ref/models/fields/#datefield
This way you won't need to update those values manually.
Sidenote: Those values are False by default so you don't need to specify auto_now_add=False.
Sadly I don't see why updating the last_updated_by field is not working properly if the Organization editing is otherwise working as intended. Changing the modified_date to work and trying again could be a good test to see if the Organization instance at hand is actually updated properly.

Get item from Django database model

I'm new to Django and I'm trying to get the item from the database.
The problem is the item is saved as a list in Django. And item[i] is not helping either. Please help me figure it out how to get the data
in the shell, I have tried
for x in NewsItem.objects.all():
print(x.tag)
this will print
['babi kutil', 'babi hutan', 'babi liar', 'hutan indonesia']
['ibu aniaya anak']
['pilkada serentak 2018', 'bandung', 'nurul arifin', 'pilwalkot bandung 2018']
['narkoba di surabaya', 'bnnp jatim']
['pilkada serentak 2018', 'banten']
But I want to get each item, not as a list.
The NewsItem Model.
class NewsItem(models.Model):
breadcrumbs = models.CharField(max_length=150, null=True)
penulis = models.CharField(max_length=100, null=True)
judul = models.CharField(max_length=200, null=True)
berita = models.TextField()
tag = models.TextField(null=True)
url = models.CharField(max_length=200, unique = True)
website = models.CharField(max_length=50, null=True)
date = models.DateTimeField()
#property
def to_dict(self):
data = {
'data': json.loads(self.url),
'tanggal': self.tanggal
}
return data
def __str__(self):
return self.url
You can use 2 for loops to achieve this and as you have mentioned tag as TextField, so you need to split it on comma.
for x in NewsItem.objects.all():
tag_text = x.tag[1:-1]
tag_list = tag_text.split(",")
for tag in tag_list:
print(tag)

django form not updating as expected

Here is my model:
class Browser(models.Model):
profile_name = models.CharField(max_length=400)
browser_type = (
('fr', 'Firefox'),
('ch', 'Chrome'),
('op', 'Opera'),
('ot', 'Other'),
)
browser_name = models.CharField(choices=browser_type, max_length=2)
device_name = models.CharField(max_length=400)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Bookmark(models.Model):
browser = models.ForeignKey(Browser, on_delete=models.CASCADE, null=True, blank=True)
title = models.TextField()
url = models.TextField()
iv = models.TextField()
salt = models.TextField()
iteration = models.IntegerField(default=1500)
tags = TaggableManager()
I only want to update certain fields, so here is the modelform
class BookmarkFormEdit(ModelForm):
class Meta:
model = Browser
exclude = ('tags', 'browser_name', 'device_name', 'profile_name')
but my problem is, values are not updating as expected . Here is the view:
def bookmark_edit(request, pk=None):
if request.method == 'POST':
bookmark = Bookmark.objects.get(pk=pk)
frm = BookmarkFormEdit(request.POST, instance=bookmark)
print(request.POST.get('iteration')) // printing correct value from front-end
if frm.is_valid():
x = frm.save()
print(x.iteration) // not saving the new value !
return JsonResponse({'status': 'created'})
else:
return JsonResponse({'error': frm.errors})
return render(request, 'bookmark_edit.html', {'pk': pk})
You are incorrectly defined model in the form. You should use Bookmark model instead of Browser.
class BookmarkFormEdit(ModelForm):
class Meta:
model = Bookmark
You may need to define fields to include/exclude as you want for this model.