Django How to get the value from many to many relationship - django

I have a product update form where I want to update the sizes of a product, with a many-to-many column relation.
I am able to get the saved values but I can't get item ID or size.
{{item.id}} shows empty value.
{% for item in form.size.value %}
<span>
<input type="checkbox" name="size" id="{{ item.id }}" value="{{ item.id }}">
<label for="{{ item.id }}">{{ item }}</label>
</span>
{% endfor %}
SIZE MODEL
class Size(models.Model):
identifier = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
size = models.CharField(max_length=200, unique=True, null=False, blank=False)
active = models.BooleanField(default=True)
date_created = models.TimeField(verbose_name='Date Created', auto_now_add=True)
date_updated = models.DateTimeField(verbose_name='Last Updated', auto_now=True)
PRODUCT MODEL
class Product(models.Model):
identifier = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
name = models.CharField(max_length=200, null=False, blank=False)
slug = models.SlugField(max_length=30, unique=True)
showcased = models.BooleanField(default=False)
recommended = models.BooleanField(default=False)
active = models.BooleanField(default=True)
price = models.DecimalField(max_digits = 5, decimal_places = 2, null=True, blank=True)
pagetitle = models.CharField(max_length=200, null=True, blank=True)
shortDescription = models.CharField(max_length=200, null=True, blank=True)
longDescription = HTMLField(null=True, blank=True)
specifications = models.TextField(null=True, blank=True)
features = models.TextField(null=True, blank=True)
care = models.TextField(null=True, blank=True)
category = models.ForeignKey(Category, on_delete=models.PROTECT)
subCategory = models.ForeignKey(SubCategory, null=True, blank=True, on_delete=models.PROTECT)
image = models.ManyToManyField(Image, blank=True)
size = models.ManyToManyField(Size, blank=True)
tag = models.ManyToManyField(Tag, blank=True)
date_created = models.TimeField(verbose_name='Date Created', auto_now_add=True)
date_updated = models.DateTimeField(verbose_name='Last Updated', auto_now=True)
I have tried different ways but not had success in getting the name or id
def updateProduct(request, pk):
categories = Category.objects.all()
sizes = Size.objects.all()
tags = Tag.objects.all()
product = Product.objects.get(id=pk)
subCategories = SubCategory.objects.filter(category=product.category.id)
images = product.image.all()
if request.method == 'POST':
form = ProductForm(request.POST, instance=product)
if form.is_valid():
form.save()
return redirect('product-panel')
form = ProductForm(instance=product)
return render(request, 'public/views/backend/product-update.html', {'categories':categories,'subCategories':subCategories, 'sizes':sizes, 'tags':tags, 'form':form, 'images':images})

Related

Annotate querying, pk

How should I query when I use pk with annotate?
I need to redirect to user profile when a guest click in link.
Models
class Posty(models.Model):
title = models.CharField(max_length=250, blank=False, null=False, unique=True)
sub_title = models.SlugField(max_length=250, blank=False, null=False, unique=True)
content = models.TextField(max_length=250, blank=False, null=False)
image = models.ImageField(default="avatar.png",upload_to="images", validators=[FileExtensionValidator(['png','jpg','jpeg'])])
author = models.ForeignKey(Profil, on_delete=models.CASCADE)
updated = models.DateTimeField(auto_now=True)
published = models.DateTimeField(auto_now_add=True)
T_or_F = models.BooleanField(default=False)
likes = models.ManyToManyField(Profil, related_name='liked')
unlikes = models.ManyToManyField(Profil, related_name='unlikes')
created_tags = models.ForeignKey('Tags', blank=True, null=True, related_name='tagi', on_delete=models.CASCADE)
class CommentPost(models.Model):
user = models.ForeignKey(Profil, on_delete=models.CASCADE)
post = models.ForeignKey(Posty, on_delete=models.CASCADE, related_name="comments")
content1 = models.TextField(max_length=250, blank=False, null=False)
date_posted = models.DateTimeField(default=timezone.now)
date_updated = models.DateTimeField(auto_now=True)
def __str__(self):
return str(self.content1)
class Profil(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
age = models.PositiveIntegerField(blank=True, null=True)
country = models.CharField(max_length=50)
user = models.OneToOneField(Account, on_delete=models.CASCADE)
avatar = models.ImageField(default="avatar.png", upload_to="images",validators=[FileExtensionValidator(['png', 'jpg', 'jpeg'])])
slug = models.SlugField(blank=True)
gender = models.CharField(max_length=6, choices=GENDER)
friends = models.ManyToManyField(Account, blank=True, related_name="Friends")
social_facebook = models.CharField(max_length=250, null=True, blank=True)
social_instagram = models.CharField(max_length=250, null=True, blank=True)
social_twitter = models.CharField(max_length=250, null=True, blank=True)
social_youtube = models.CharField(max_length=250, null=True, blank=True)
social_linkedin = models.CharField(max_length=250, null=True, blank=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
Views
if tag == None:
my_tag = Posty.objects.annotate(
latest_comment = Subquery(CommentPost.objects.filter(post=OuterRef('id')).values('content1').order_by('-date_posted')[:1]),
my_author=Subquery(CommentPost.objects.filter(post=OuterRef('id')).values('user__user__username').order_by('-date_posted')[:1]),
)
I got a correct username, but I can't get a correct redirect:
Unfortunately, you need to annotate the CommentPost's id information as well with the queryset just like you added the username information. That will end up being a lot of subquery added to the original queryset. Rather I would suggest to use prefetch related to preload the CommentPost information with the original queryset (for reducing DB hits) and directly access that information from template. For example:
# view
my_tag = Posty.objects.prefetch_related('commentpost_set')
# template
{% for post in my_tag %}
<span> {{post.commentpost_set.last.content1}}<span>
<span> {{post.commentpost_set.last.user.username}}<span>
{% endfor %}
Also, last is a queryset function which returns the last object of a given queryset. I can access the CommentPost queryset from a Posty object by reverse querying.

Select a model instance from HTML form on Django

I am trying to get my html form to allow me to pass the company model instance. As of now, I can pull the names of each company instance, however, what would I put into the value attibute of the option field to have it select the instance correctly?
<option value="what to put here?">{{Company.name}}</option>
I was hoping to do this through HTML forms and not Django forms as I have used AJAX to make a nice little live-updating interface.
models.py
class Company(models.Model):
name = models.CharField(max_length=30, null=True, blank=True)
email = models.CharField(max_length=40, null=True, blank=True)
phone = models.CharField(max_length=15, null=True, blank=True)
address = models.CharField(max_length=100, null=True, blank=True)
notes = models.CharField(max_length=400, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True, blank=True)
updated = models.DateTimeField(auto_now=True, blank=True)
class Meta:
ordering = ["name"]
def __str__(self):
return self.name
class Contact(models.Model):
firstname = models.CharField(max_length=20, null=True, blank=True)
lastname = models.CharField(max_length=20, null=True, blank=True)
email = models.CharField(max_length=40, null=True, blank=True)
phone = models.CharField(max_length=15, null=True, blank=True)
title = models.CharField(max_length=20, null=True, blank=True)
notes = models.CharField(max_length=400, null=True, blank=True)
company = models.ForeignKey(Company, on_delete=models.CASCADE, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ["lastname"]
def __str__(self):
return self.firstname
views.py
class contact_manager(ListView):
template_name = 'crm/contact_manager.html'
context_object_name = 'contact_manager'
queryset = Contact.objects.all()
def get_context_data(self, **kwargs):
context = super(contact_manager, self).get_context_data(**kwargs)
context['contact'] = Contact.objects.all()
context['company_list'] = Company.objects.all()
# And so on for more models
return context
contact_manager.html
<div class="form-group">
<select class="form-control" name="company" placeholder="Company">
<option value="">Please select a company</option>
{% for Company in company_list %}
<option value="{{Company.name}}">{{Company.name}}</option>
{% endfor %}
</select>
</div>
If you are looking for a unqiue identifier for each option, that links to a model instance on the backend, that is what the ID field is for (Company.id):
<option value="{{ Company.id }}">{{Company.name}}</option>
Then on the backend you can retrieve the model with the posted id:
Company.get(id=posted_id)
Note: id is by default added to your model as the primary key and is a auto incrememting integer.

Checkboxes True or False not loading into form properly

I'm using a ModelForm to load a Form and all of the values are pulling properly except the checkboxes. They always load in unchecked whether or not their state is True or False.
I've tried creating the checkbox fields like:
<label>
<input type="checkbox" checked='{{ form.instance.hot }}'>
<span>Hot{{ form.hot }}</span>
</label>
<li>CSR: {{ form.csr }}</li>
{% if request.user|has_group:"Customer Service Manager" %}
<li>Documents: {{ form.documents }}</li>
{% endif %}
<li>Notes: {{ form.notes }}</li>
<li>First Name:{{ form.first_name }}</li>
<li>Last Name: {{ form.last_name }}</li>
<li>Address: {{ form.address }}</li>
Which results in the checkbox always being checked instead matching what's in the table for that client.
models.Client
class Client(models.Model):
#Account Information
client_status =[("1", "Active"), ("0", "Inactive")]
WHOPAYS =[("0", "Not Applicable"), ("1", "They Pay"), ("2", "We Pay")]
hot = models.BooleanField(default=False, required=False)
region = models.ForeignKey('Region', to_field='region_id', on_delete=None, null=True, blank=True)
sub_account = models.ForeignKey('self', on_delete=models.CASCADE, related_name='sub_account_of_client', null=True, blank=True)
created = models.DateField('Account Creation', auto_now_add=True)
client_class = models.ForeignKey('ClientClass', on_delete=None, null=True, blank=True)
category = models.ForeignKey('ClientCategory', on_delete=None, null=True, blank=True)
they_pay = models.BooleanField('They Pay', default = False, required=False)
we_pay = models.BooleanField('We Pay', default = False, required=False)
csr = models.ForeignKey(settings.AUTH_USER_MODEL, to_field='extension', on_delete=None, blank=True, null=True, limit_choices_to= Q( groups__name = 'Customer Service'))
#Upload location /<ClientID>/documents/*
documents = models.FileField(null=True, blank=True, upload_to=client_directory_path)
notes = models.TextField(null=True, blank=True)
active_status = models.CharField('Status', max_length=1, choices=client_status, default="1")
client = models.CharField('Client/Company Name',max_length=200, null=True, blank=True)
account_number = models.CharField(max_length=50, null=True, blank=True)
#Contact Information
first_name = models.CharField('First Name', max_length = 200, null=True, blank=True)
last_name = models.CharField('Last Name', max_length = 200, null=True, blank=True)
email = models.EmailField(max_length = 254, null=True, blank=True)
main_phone = models.CharField(null=True, blank=True, max_length=50)
alt_phone = models.CharField(null=True, blank=True, max_length=50)
fax = PhoneField(null=True, blank=True)
follow_up = models.DateField('Date to Follow Up', default=three_days())
#Billing and Shipping Addresses
address = models.CharField('Address Line 1', max_length=200, null=True, blank=True)
address2 = models.CharField('Address Line 2', max_length=200, null=True, blank=True)
city = models.CharField('City', max_length=200, null=True, blank=True)
zipcode = models.CharField('Zip Code', max_length=200, null=True, blank=True)
state = models.CharField('State', max_length=2, null=True, blank=True, choices=STATE_CHOICES)
country = models.CharField('Country', max_length=200, null=True, blank=True, default='USA')
def __str__(self):
if self.sub_account:
return '{0}: Sub-Account for {1}'.format(self.client, self.sub_account)
else:
return '{0} - {1}'.format(self.client, self.zipcode)
views.client_view
def client_view(request):
FormSet = modelformset_factory(Client, form=ClientSheet, extra=0)
if request.method == 'POST':
formset = FormSet(request.POST, request.FILES)
if formset.is_valid():
formset.save(commit=False)
formset.save()
return HttpResponseRedirect('/client/')
else:
query = Client.objects.filter(follow_up__lte=date.today(), csr__extension=request.user.extension).order_by('-hot')
currentcall = Client.objects.filter(follow_up__lte=date.today(), csr__extension=request.user.extension).order_by('-hot').first()
paginator = Paginator(query, 1) # Show 1 forms per page
page = request.GET.get('page')
try:
objects = paginator.page(page)
except PageNotAnInteger:
objects = paginator.page(1)
except EmptyPage:
objects = paginator.page(paginator.num_pages)
page_query = Client.objects.filter(id__in=[object.id for object in objects])
formset = FormSet(queryset=page_query)
context = {'objects': objects, 'formset': formset, 'callqueue': query, 'currentcall': currentcall}
return render(request, 'main/client.html', context)
Whenever Checkbox will always be checked as soon as you pass checked attribute.
Your template should look like
<input type="checkbox" {{ form.instance.hot|yesno:"checked,'',''" }}>

Django odd boolean bahavior

I have a boolean field for whether or not an item is active:
is_active = models.BooleanField(default=True)
It seems pretty straightforward, my template will display items that are active:
{% for p in products|dictsortreversed:"id" %}
{% if p.is_active %}
<a href="{{ p.get_absolute_url }}">
{{ p.name }}
</a>
{% endif %}
For some reason all items are returned even if the field is 0 in the database. When I uncheck the boolean field in the django admin, it updates correctly to 0 in the database, but still shows as being checked in the admin...
It seems like django is reading the field as True, regardless of the boolean value.
Model
class Product(models.Model):
name = models.CharField(max_length=255, unique=True)
slug = models.SlugField(max_length=255, unique=True, help_text='Unique value for product page URL, created from name')
price = models.DecimalField(max_digits=9, decimal_places=2, blank=True, default=0.00)
old_price = models.DecimalField(max_digits=9, decimal_places=2, blank=True, default=0.00)
image = models.CharField(max_length=50)
is_active = models.BooleanField(default=True)
quantity = models.IntegerField()
description = models.TextField()
meta_keywords = models.CharField('Meta Keywords', max_length=255, help_text='Comma-delimited set of SEO keywords for meta tag')
meta_description = models.CharField('Meta Description', max_length=255, help_text='Content for description meta tag')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
categories = models.ForeignKey(Category, null=True)
publish_date = models.DateField(blank=True, null=True)
issue_one = models.CharField(blank=True, null=True, max_length=255)
issue_two = models.CharField(blank=True, null=True, max_length=255)
issue_three = models.CharField(blank=True, null=True, max_length=255)
class Meta:
db_table = 'products'
ordering = ['-created_at']
def __unicode__(self):
return self.name
#models.permalink
def get_absolute_url(self):
return ('catalog_product', (), {'product_slug': self.slug})
View:
def index(request, template_name="catalog/index.html"):
""" site home page """
page_title = 'Visible Language Ordering'
return render_to_response(template_name, locals(), context_instance=RequestContext(request))

dynamic formset doesn't handle file upload data properly

I'm building a dynamic formset based on the dynamic-formset jquery plug-in: I've constructed an alpha model that works except that it doesn't commit data from any of the fileupload fields to the database. Have I blown my formset view function?
#forms.py
class PostEntryForm(ModelForm):
class Meta:
model = PostEntry
ContactFormset = formsets.formset_factory(PostEntryForm)
#models.py
class PostEntry(models.Model):
client = models.CharField(max_length=50, choices=CLIENT_CHOICES)
job_number = models.CharField(validators=[RegexValidator(regex='^\w{8}$', message='Please enter a valid job number', code='nomatch')], max_length=8, unique=False, blank=False, null=False)
cell_number = models.CharField(max_length=4, unique=False, blank=True, null=True)
post_title = models.CharField(max_length=64, unique=False, blank=True, null=True)
date = models.DateField(("Date"), default=datetime.date.today)
post_type = models.CharField(max_length=64, choices=POST_CHOICES)
post_round = models.CharField(max_length=20, blank=False, null=False)
docfile = models.FileField(upload_to=content_file_name, blank=True, null=True, max_length=300)
url_link = models.URLField(blank=True, null=False, max_length=300)
misc_link = models.CharField(max_length=64, blank=True, null=True)
link_misc = models.FileField(upload_to=content_file_name, blank=True, null=True, max_length=300)
misc_link2 = models.CharField(max_length=64, blank=True, null=True)
link_misc2 = models.FileField(upload_to=content_file_name, blank=True, null=True, max_length=300)
mobile_view_url = models.URLField(validators=[RegexValidator(regex='^(http|https)://', message='url must begin with http or https', code='nomatch')], blank=True, null=False, max_length=300)
link_pdf = models.FileField(upload_to=content_file_name, blank=True, null=True, max_length=300)
link_html = models.FileField(upload_to=content_file_name, blank=True, null=True, max_length=300)
link_report = models.FileField(upload_to=content_file_name, blank=True, null=True, max_length=300)
link_text = models.FileField(upload_to=content_file_name, blank=True, null=True, max_length=300)
link_zip = models.FileField(upload_to=content_file_name, blank=True, null=True, max_length=300)
def __unicode__ (self):
return u'%s %s %s %s %s' % (self.client, self.job_number, '-', self.cell_number, self.post_title)
def save(self, force_insert=False, force_update=False):
self.job_number = self.job_number.upper()
self.cell_number = self.cell_number.upper()
super(PostEntry, self).save(force_insert, force_update)
class Meta:
ordering = ['-date', 'cell_number']
class Admin:
pass
#views.py
def formset(request, formset_class, template):
if request.method == 'POST':
formset = formset_class(request.POST, request.FILES)
if formset.is_valid():
for form in formset.forms:
form.save()
return HttpResponseRedirect('/main')
else:
formset = formset_class()
return render_to_response(template, {'formset': formset},
context_instance=RequestContext(request))
If it's not sending just your fileupload, I guess it could be a missing enctype attribute on your form.
So, try to do this:
<form action="" method="POST" enctype="multipart/form-data">
{{ formset.management_form }}
{% for form in formset %}
{{ form }}
{% endfor %}
</form>