How to update image fields using Django forms - python

I am attempting to create a blogging application and in it I have 2 forms, one for editing pre-existing posts, and the other for creating them. However, I am unable to get updated images, when the edit form is submitted. All textual data goes through...
Models.py:
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name= 'blog_posts')
short_description = models.TextField()
updated_on = models.DateTimeField(auto_now=True)
content = RichTextUploadingField()
created_on = models.DateTimeField(auto_now=True)
status = models.IntegerField(choices=Status, default=0)
cover_image = models.ImageField(upload_to = 'coverimages', null =True, blank = True)
captioned_image = models.ImageField(upload_to = 'captionedimages', null=True, blank = True)
caption = models.CharField(max_length=300)
featured = models.IntegerField(choices=Featured, default=1)
category = models.ForeignKey(PostCategory, on_delete=models.CASCADE, null=True, blank=True)
embedded_code = models.TextField(blank=True, null=True, default='null')
tags = models.ManyToManyField(Tag, blank=True)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
forms.py:
class EditForm(forms.Form):
title = forms.CharField(max_length=100, label='Post Title')
short_description = forms.CharField(widget=forms.Textarea(attrs={"rows":3, "cols":100}))
content = forms.CharField(widget=CKEditorUploadingWidget())
status = forms.NullBooleanField(label='Ready to Publish?')
image = forms.ImageField(label='Select a cover image:', required=False)
captioned_image = forms.ImageField(label='Select a captionable image:', required=False)
caption = forms.CharField(max_length=200)
try:
category = forms.ModelChoiceField(queryset=PostCategory.objects.all())
except:
category = forms.ChoiceField(choices= ('default'))
embed = forms.CharField(widget=forms.Textarea(attrs={"rows":3, "cols":100}))
tags = forms.CharField(widget=forms.Textarea(attrs = {"rows":1, "cols":150}))
editpost.html:
{% load widget_tweaks %}
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %} {{ form.media }}
<legend>Edit Post: {{ post }}</legend>
<div class="form-group">
<label class="col-form-label mt-4" for="inputDefault">Title</label>
{% render_field form.title class="form-control" %}
</div>
<div class="form-group">
<label class="form-label mt-4" for="exampleTextarea"
>Short Description</label
>
{% render_field form.short_description class="form-control" %}
</div>
<div class="form-group">
<label class="col-form-label mt-4" for="inputDefault">Content</label>
{{ form.content }}
</div>
<div class="form-group">
<label class="form-label mt-4" for="exampleSelect1"
>Ready To Publish?</label
>
{% render_field form.status class="form-select" id="exampleSelect1"%}
</div>
<div class="form-group">
<label class="form-label mt-4" for="formFile">Cover Image</label>
{% render_field form.image class="form-control" id="formFile"%}
{% if post %}
<br>
<p>Current Image:</p>
<img src="{{ post.cover_image.url }}" alt="" style="height: 400px;">
{% endif %}
</div>
<fieldset>
<div class="form-group">
<label class="form-label mt-4" for="formFile"
>Captioned Image</label
>
{% render_field form.captioned_image class="form-control" %}
{% if post %}
<br>
<p>Current Image:</p>
<img src="{{ post.captioned_image.url }}" alt="" style="height: 400px;">
{% endif %}
</div>
<div class="form-group">
<label class="col-form-label mt-4" for="inputDefault"
>Caption</label
>
{% render_field form.caption class="form-control" %}
</div>
</fieldset>
<div class="form-group">
<label class="col-form-label mt-4" for="inputDefault">Category</label>
{% render_field form.category class="form-select"%}
</div>
<div class="form-group">
<label class="col-form-label mt-4" for="inputDefault">Embed</label>
{% render_field form.embed class="form-control"%}
</div>
<div class="form-group">
<label class="col-form-label mt-4" for="inputDefault">Tags</label>
{% render_field form.tags class="form-control"%}
</div>
<br />
<button type="submit" class="btn btn-primary">Submit</button>
</form>
After the form is submitted, the image is not saved in the media/coverimages folder, and the development server returns:
Not Found: /media/images.jpg
[23/Jan/2022 09:16:24] "GET /media/images.jpg HTTP/1.1" 404 3786
One thing I have noticed is that if I use the admin site, the image uploads properly, which leads me to believe that perhaps issue is with the form, or how the form is being handled
EDIT:
views.py:
# Converts tag string from a form to a nice iterable list
def tagsplitter(input):
input = str(input)
tags = input.split(', ')
return tags
# Fetches all the tags of a QueryObject and returns tags in a nice list
def tagstringer(object):
tags = object.tags.all()
taglist = []
for tag in tags:
taglist.append(tag.tag)
str1 = ", "
return str1.join(taglist)
#staff_member_required(login_url='login')
def edit_post(request, slug):
context = {}
post = Post.objects.get(slug=slug)
context.update({'post': post})
if request.method == "POST":
form = EditForm(request.POST, request.FILES)
if form.is_valid():
image_path = post.cover_image.path
if os.path.exists(image_path):
os.remove(image_path)
title = request.POST.get('title')
short_description = request.POST.get('short_description')
content = request.POST.get('content')
statusraw = request.POST.get('status')
if str(statusraw) == 'true':
status = 1
else:
status = 0
cover_image = request.FILES.get('image')
captioned_image = request.FILES.get('captioned_image')
caption = request.POST.get('caption')
category = request.POST.get('category')
tags = tagsplitter(request.POST.get('tags'))
embed = request.POST.get('embed')
print(f"cover image: {cover_image}")
if cover_image is not None:
if captioned_image is not None:
# Add both images
newpost = Post.objects.filter(pk=post.pk).update(title=title, cover_image = cover_image, captioned_image=captioned_image, short_description=short_description, content=content, status=status, caption=caption, category=category, embedded_code=embed)
else:
print('Adding cover image only')
# Add only cover image
newpost = Post.objects.filter(pk=post.pk).update(title=title, cover_image = cover_image, short_description=short_description, content=content, status=status, caption=caption, category=category, embedded_code=embed)
else:
if captioned_image is not None:
# Add only captioned image
newpost = Post.objects.filter(pk=post.pk).update(title=title, captioned_image=captioned_image, short_description=short_description, content=content, status=status, caption=caption, category=category, embedded_code=embed)
else:
# Add neither
newpost = Post.objects.filter(pk=post.pk).update(title=title, short_description=short_description, content=content, status=status, caption=caption, category=category, embedded_code=embed)
newpost = Post.objects.get(title = title)
newpost.tags.clear()
for tag in tags:
tag = Tag.objects.update_or_create(tag = tag)
newpost.tags.add(tag[0])
return redirect('blogger:post', slug = slug)
else:
tagstr = tagstringer(post)
init_dict = {
'title': post.title,
'content': post.content,
'short_description': post.short_description,
'status': post.status,
'cover_image': post.cover_image,
'caption': post.caption,
'embed': post.embedded_code,
'category':post.category,
'tags': tagstr
}
form = EditForm(initial = init_dict)
context.update({'form': form})
return render(request, template_name="blogger/edit_post.html", context=context)

Related

Can't display picture on my django social app using imageField?

I need some fresh eyes, what am I missing here? In my Post Model imageField is defined as "picture" to be uploaded on the site, I seed it on my admin panel, it gets uploaded just fine but I can't seem to make it appear on the page: http://127.0.0.1:8000/posts/. I get ValueError at /posts/
The 'picture' attribute has no file associated with it. Highlited line is line 257, in post_comment_create_view
return render(request, 'network/posts.html', context)
Model:
class Post(models.Model):
# id is created automatically by Django
picture = models.ImageField(upload_to='images', blank=True, validators=[FileExtensionValidator(['png', 'jpg', 'jpeg'])])
content = models.TextField()
liked = models.ManyToManyField(Profile, blank=True, related_name="likes")
author = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ('-created',)
def __str__ (self):
return str(self.content[:20])
Forms:
class PostModelForm(forms.ModelForm):
content = forms.CharField(widget=forms.Textarea(attrs={'rows':2}))
class Meta:
model = Post
fields = ('content', 'picture')
Views:
#login_required
def post_comment_create_view(request):
qs = Post.objects.all()
profile = Profile.objects.get(user=request.user)
#Setting up pagination
p = Paginator(qs, 5)
page = request.GET.get('page')
post_list = p.get_page(page)
#Post form, comment form
p_form = PostModelForm()
c_form = CommentModelForm()
post_added = False
profile = Profile.objects.get(user=request.user)
if 'submit_pForm' in request.POST:
print(request.POST)
p_form = PostModelForm(request.POST, request.FILES)
if p_form.is_valid():
instance = p_form.save(commit=False)
instance.author = profile
instance.save()
p_form = PostModelForm()
post_added = True
if 'submit_cForm' in request.POST:
c_form = CommentModelForm(request.POST)
if c_form.is_valid():
instance = c_form.save(commit=False)
instance.user = profile
instance.post = Post.objects.get(id=request.POST.get('post_id'))
instance.save()
c_form = CommentModelForm()
context = {
'qs': qs,
'profile': profile,
'p_form': p_form,
'c_form': c_form,
'post_added': post_added,
'post_list': post_list,
}
return render(request, 'network/posts.html', context)
HTML:
{% block body %}
<div>
<div class="border border-light rounded" style="width: 25rem;">
{% if post_added %}
<div id="alertFade" class="alert alert-success" role="alert">Post added!</div>
{% endif %}
<form action="" method="POST" enctype="multipart/form-data" class="form-group">
{% csrf_token %}
{{p_form}}
<button type="submit" class="btn btn-sm btn-success" name="submit_pForm">Send Post</button>
</form>
</div>
{% for obj in post_list %}
<div class="card center" style="width: 30rem;">
<div class="card-head" style="background-color: #d0e2bc;">
<img width="50px" class="avatar img-thumbnail rounded-circle z-depth-2 ml-1" src={{obj.author.avatar.url}}> {{ obj.author.user }} - {{ obj.created|naturaltime }}
{% if request.user == obj.author.user %}
<button class="btn btn-sm btn-success float-right mt-2 mr-1">Delete</button>
<button class="btn btn-sm btn-success float-right mr-1 mt-2">Edit</button>
{% endif %}
</div>
<div class="card-body">
<img src={{obj.picture.url}}> <br>
<p class="card-text">{{obj.content|safe}}</p>
<hr>
</div>
<button class="cmt_btn ui button mb-5">show / hide comments</button>
<div class="comment-box">
{% if obj.comment_set.all %}
{% for c in obj.comment_set.all %}
<img width="20px" class="avatar img-thumbnail rounded-circle"src={{c.user.avatar.url}} alt="">
<span>{{ c.user }}</span>
<div class="mt-2">{{ c.body }}</div>
{% endfor %}
{% endif %}
There should be quotes around the src:
<img src={{obj.picture.url}}> <!-- will not work -->
Should be:
<img src="{{obj.picture.url}}"> <!-- works -->
This is for the tag attributes. For content within the tag, what you have is fine, no quotes. This is good:
<span>{{ c.user }}</span> <!-- works -->
I solved it, the solution is that I had to check if the img exists:
{% if obj.picture %}
<img src="{{obj.picture.url}}"> <br/>
{% endif %}

ValueError: Cannot assign "1": "Topic.board" must be a "Board" instance

I know there are a bunch of questions addressing this issue, but I haven't solved it out yet. please any help i tried many solutions but didn't work
models.py
class Board(models.Model):
name = models.CharField(max_length=50,unique=True)
description = models.CharField(max_length=150)
def __str__(self):
return self.name
class Topic(models.Model):
subject = models.CharField(max_length=255)
board = models.ForeignKey(Board,related_name='topics',on_delete=models.CASCADE)
created_by = models.ForeignKey(User,related_name='topics',on_delete=models.CASCADE)
created_dt = models.DateTimeField(auto_now_add=True)
class Post(models.Model):
message = models.TextField(max_length=4000)
topic = models.ForeignKey(Topic, related_name='posts',on_delete=models.CASCADE)
created_by = models.ForeignKey(User,related_name='posts',on_delete=models.CASCADE)
created_dt = models.DateTimeField(auto_now_add=True)
view.py
def new_topic(request,board_id):
board = get_object_or_404(Board,pk=board_id)
if request.method == 'POST':
subject = request.POST['subject']
message = request.POST['message']
user = User.objects.first()
topic = Topic.objects.create(
subject=subject,
board=board_id,
created_by=user
)
post = Post.objects.create(
message=message,
topic=topic,
created_by=user
)
new_topic.html
{% extends 'base.html' %}
{% block title %}Start a New Topic{% endblock %}
{% block breadcrumb %}
<li class="breadcrumb-item">Boards</li>
<li class="breadcrumb-item">{{ board.name }}</li>
<li class="breadcrumb-item active">New topic</li>
{% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
<div class="form-group">
<label for="id_subject">Subject</label>
<input type="text" class="form-control" id="id_subject" name="subject">
</div>
<div class="form-group">
<label for="id_message">Message</label>
<textarea class="form-control" id="id_message" name="message" rows="5"></textarea>
</div>
<button type="submit" class="btn btn-success">Add</button>
</form>
{% endblock %}
I'm fairly new to Django. How would I go about resolving that?
in new_topic(views.py), convert board=board_id to board=board

Store multiple inputs values of form in single json to store in model field. - Django

I am working on a project which is online printing ordering service.
Here on the order page I am getting different attributes of product in radio button list in the form, and all the attributes I want to store in a single json in database.
models.py
class Product(models.Model):
prod_ID = models.AutoField("Product ID", primary_key=True)
prod_Name = models.CharField("Product Name", max_length=30, null=False)
prod_Desc = models.CharField("Product Description", max_length=2000, null=False)
prod_Price = models.IntegerField("Product Price/Piece", default=0.00)
prod_img = models.ImageField("Product Image", null=True)
def __str__(self):
return "{}-->{}".format(self.prod_ID,
self.prod_Name)
# this is the order table , there is a "attribute_field" I wantto store the attributes in this field
# as JSON.
class Order(models.Model):
order_id = models.AutoField("Order ID", primary_key=True)
user_id = models.ForeignKey(User, on_delete=models.CASCADE, null=False, verbose_name="Customer ID")
prod_id = models.ForeignKey(Product, on_delete=models.CASCADE, null=False, verbose_name="Product ID")
quantity = models.ImageField('Product Quantity', max_length=10, default=500)
attribute_value = models.CharField("Item Details JSON", max_length=2000, null=False)
order_date = models.DateField("Order Date", auto_now_add=True, null=False)
order_job_title = models.CharField("Name of Company/Business", max_length=100, null=False)
order_desc = models.CharField("Details for Product", max_length=1000, null=False)
product_img = models.ImageField("Template Image", null=False)
address = models.CharField("Customer Address ", max_length=100, null=False)
state = models.CharField("Customer State", max_length=30, null=False)
city = models.CharField("Customer City", max_length=30, null=False)
postal_code = models.IntegerField("Area Pin Code", null=False)
order_price = models.DecimalField(max_digits=8, decimal_places=2, default=0000.00)
class Size(models.Model):
size_id = models.AutoField("Size ID", primary_key=True, auto_created=True)
prod_size = models.CharField("Product Size", max_length=20, null=False)
def __str__(self):
return "{size_id}-->{prod_size}".format(size_id=self.size_id,
prod_size=self.prod_size)
class Color(models.Model):
color_id = models.AutoField("Color ID", primary_key=True, auto_created=True)
prod_color = models.CharField("Product Color", max_length=50, null=False)
def __str__(self):
return "{color_id}-->{prod_color}".format(color_id=self.color_id,
prod_color=self.prod_color)
class PaperChoice(models.Model):
paper_id = models.AutoField("Paper Choice ID", primary_key=True, auto_created=True)
paper_choices_name = models.CharField("Paper Choices", max_length=50, null=False)
def __str__(self):
return "{}-->{}".format(self.paper_id,
self.paper_choices_name)
class SizeProductMapping(models.Model):
size_p_map_id = models.AutoField("Size & Product Map ID", primary_key=True, auto_created=True)
size_id = models.ForeignKey(Size, null=False, on_delete=models.CASCADE, verbose_name="Size ID")
prod_id = models.ForeignKey(Product, null=False, on_delete=models.CASCADE, verbose_name="Product Id")
class ColorProductMapping(models.Model):
color_p_map_id = models.AutoField("Color & Product Map ID", primary_key=True, auto_created=True)
color_id = models.ForeignKey(Color, null=False, on_delete=models.CASCADE, verbose_name="Color ID")
prod_id = models.ForeignKey(Product, null=False, on_delete=models.CASCADE, verbose_name="Product Id")
class PaperChoiceProductMapping(models.Model):
paper_p_map_id = models.AutoField("Paper Choices & Product Map ID", primary_key=True, auto_created=True)
paper_id = models.ForeignKey(PaperChoice, null=False, on_delete=models.CASCADE, verbose_name="Paper ID")
prod_id = models.ForeignKey(Product, null=False, on_delete=models.CASCADE, verbose_name="Product Id")
this is my views.py and it is incomplete , I want to store the forms data in the model using this
view.
views.py
#here in thi view method I am only getting data from models but not getting template data to store in the the model,
# I know I haven't taken inputs from the form here
# I haven't done because I don't know what logic I should use here.
def order(request, id):
products = Product.objects.all()
sizesList = []
ColorsList = []
PaperChoiceProductsList = []
try:
sizesMap = SizeProductMapping.objects.filter(prod_id=id)
sizesList = [data.size_id.prod_size for data in sizesMap]
except AttributeError:
pass
try:
colorMap = ColorProductMapping.objects.filter(prod_id=id)
ColorsList = [data.color_id.prod_color for data in colorMap]
except AttributeError:
pass
try:
PaperChoiceProductMap = PaperChoiceProductMapping.objects.filter(prod_id=id)
PaperChoiceProductsList = [data.paper_id.paper_choices_name for data in PaperChoiceProductMap]
except AttributeError:
pass
context = {'products': products,
'sizesList': sizesList,
"ColorsList": ColorsList,
"PaperChoiceProductsList": PaperChoiceProductsList,
}
return render(request, 'user/order.html', context)
order.html
{% extends 'user/layout/userMaster.html' %}
{% block title %}Order{% endblock %}
{% block css %}
form
{
position:relative;
}
.tasksInput
{
margin-right:150px;
}
label
{
vertical-align: top;
}
{% endblock %}
{% block header %}
{% endblock %}
{% block main %}
<div class="container">
<div>
<div class="row rounded mx-auto d-block d-flex justify-content-center">
<button class="btn btn-secondary my-2 mr-1">Custom</button>
<button class="btn btn-secondary my-2 ml-1">Package</button>
</div>
<div class="row">
<div class="col-4">
<div class="card border border-secondary">
<div class="card body mx-2 mt-4 mb-2">
{% for product in products %}
<a id="{{ product.prod_ID }}" class="card-header" style="font-size:5vw;color:black;"
href="{% url 'user-order' product.prod_ID %}">
<h5 class="h5">{{ product.prod_ID }}. {{ product.prod_Name }}</h5></a>
<div class="dropdown-divider"></div>
{% endfor %}
</div>
</div>
</div>
<div class="col-8">
<form>
<div class="card mx-2 my-2 border border-secondary">
<div class="my-2">
<!-- The data I want to store in JSON starts from here -->
{% if sizesList %}
<div class="form-group">
<div class="form-group row mx-2">
<label for="sizeList"
class="form-control-label font-weight-bold card-header col-4 ml-4"
style="background-color:#e3e4e6"><h5>Sizes : </h5></label>
<div id="sizeList">
{% for s in sizesList %}
<input id="{{s}}" class="mx-2 my-auto" type="radio" name="size">
<label for="{{s}}">{{s}}</label><br>
{% endfor %}
</div>
</div>
</div>
{% endif %}
{% if ColorsList %}
<div class="form-group">
<div class="form-group row mx-2">
<label for="ColorsList"
class="form-control-label font-weight-bold card-header col-4 ml-4"
style="background-color:#e3e4e6"><h5>Colors : </h5></label>
<div id="ColorsList">
{% for c in ColorsList %}
<input id="{{c}}" class="mx-2 my-auto" type="radio" name="Color">
<label for="{{c}}">{{c}}</label><br>
{% endfor %}
</div>
</div>
</div>
{% endif %}
{% if PaperChoiceProductsList %}
<div class="form-group">
<div class="form-group row mx-2">
<label for="ColorsList"
class="form-control-label font-weight-bold card-header col-4 ml-4"
style="background-color:#e3e4e6"><h5>Paper Choice : </h5></label>
<div id="PaperChoiceProductsList">
{% for pc in PaperChoiceProductsList %}
<input id="{{pc}}" class="mx-2 my-auto" type="radio" name="PaperChoice">
<label for="{{pc}}">{{pc}}</label><br>
{% endfor %}
</div>
</div>
</div>
{% endif %}
<!-- The Data I want to store in the JSON ends here -->
</div>
</div>
</div>
</form>
</div>
</div>
<div class="row rounded mx-auto d-block d-flex justify-content-center">
<button class="btn btn-success my-2">Place Order</button>
</div>
</div>
</div>
{% endblock %}
As mentioned in above template comment I want to store that data in single JSON.
Can you please help me to create a view for it.
urls.py
path('order/<int:id>', views.order, name="user-order"),
I used jason dump method to store value in single json object and then passed it to the field and it is working for me.
views.py
import json
def order(request, id):
products = Product.objects.all()
sizesList = []
ColorsList = []
PaperChoiceProductsList = []
value = {}
try:
sizesMap = SizeProductMapping.objects.filter(prod_id=id)
sizesList = [data.size_id.prod_size for data in sizesMap]
except AttributeError:
pass
try:
colorMap = ColorProductMapping.objects.filter(prod_id=id)
ColorsList = [data.color_id.prod_color for data in colorMap]
except AttributeError:
pass
try:
PaperChoiceProductMap = PaperChoiceProductMapping.objects.filter(prod_id=id)
PaperChoiceProductsList = [data.paper_id.paper_choices_name for data in PaperChoiceProductMap]
except AttributeError:
pass
if request.method == 'POST':
if request.method == 'POST':
customer_id = request.user
product = Product.objects.get(prod_ID=id)
product_id = product
try:
quantity = request.POST['quantity']
print(quantity)
except MultiValueDictKeyError:
pass
try:
size = request.POST['size']
value.update(size=size)
except MultiValueDictKeyError:
pass
try:
Colour = request.POST['Color']
value.update(Colour=Colour)
except MultiValueDictKeyError:
pass
try:
Paper_Choice = request.POST['PaperChoice']
value.update(Paper_Choice=Paper_Choice)
except MultiValueDictKeyError:
pass
attribute_value = json.dumps(value)
order_store = Order(user_id=customer_id, prod_id=product_id, quantity=quantity, attribute_value=attribute_value,
order_job_title=Job_title, order_desc=Order_Detail, address=User_Address, state=State,
city=City, postal_code=Postal_Code, product_img=TemplateValue)
order_store.save()
context = {'products': products,
'sizesList': sizesList,
"AqutousCoatingProductList": AqutousCoatingProductList,
"ColorsList": ColorsList,
"PaperChoiceProductsList": PaperChoiceProductsList,
}
return render(request, 'user/order.html', context)

How to render Model field in Django, either it contains text or image?

In models.py, question field contains text and question_img filed contains image. Questions may be text or image. If question filed contains text, question_img field should be empty and if question_img filed contains image, question filed should be empty. So, how to render text question or image question based on condition? If question field is empty then it should render question_img from Database vice-versa.
models.py:
class Questions(models.Model):
paper = models.CharField(max_length=10, default='None')
qs_no = models.IntegerField(default=None)
question = models.TextField(max_length=500)
question_img = models.ImageField(null=True, blank=True)
option_a = models.CharField(max_length=100)
option_b = models.CharField(max_length=100)
option_c = models.CharField(max_length=100)
option_d = models.CharField(max_length=100)
ans = models.CharField(max_length=50)
forms.py:
class QuestionsForm(forms.ModelForm):
paper = forms.CharField(widget=forms.Select(choices = PAPER_CHOICES))
class Meta:
model=Questions
fields=[
'paper',
'qs_no',
'question',
'question_img',
'option_a',
'option_b',
'option_c',
'option_d',
'ans',
]
views.py:
def questions(request):
if not request.user.is_superuser:
return render(request, 'login.html')
else:
if request.method == 'POST':
form = QuestionsForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('questions')
else:
return HttpResponseRedirect('questions')
else:
form = QuestionsForm()
return render(request, 'questions.html', {'form':form})
def render_questions(request):
print(f'user in render_questions is {request.user.username}', flush=True)
if not request.user.is_authenticated:
return render(request, 'login.html')
else:
global exam_session
exam_session = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10))
print(f"session id in render ques is {exam_session}", flush=True)
questions = Questions.objects.all()
ques = []
qs_no = 1
for q in questions:
que = {}
que['qs_no'] = qs_no
qs_no = qs_no + 1
que['question'] = q.question
que['id'] = q.id
que['option_a'] = q.option_a
que['option_b'] = q.option_b
que['option_c'] = q.option_c
que['option_d'] = q.option_d
ques.append(que)
print(f"ques: {ques}", flush=True)
return render(request, 'report.html', {'ques': ques})
template.html:
<form id="myform" name="myform" action="answer" method="POST">
{% csrf_token %}
<div class="questionContainer">
{% for question in ques %}
<div class="questiondiv" data-questionId="{{ question.id }}">
<div class="bghead1">
<h5><strong>Question {{ question.qs_no }}.</strong></h5>
</div>
<div class="font mrl">
<h5><input type="hidden" class="form-check-input" name="question" value="{{ question.question }}">{{ question.question }}</h5>
</div>
<div class="radio pad">
<label><input type="radio" class="form-check-input" name="question{{question.qs_no}}" value="{{question.option_a}}"> A) {{ question.option_a }}</label>
</div>
<div class="radio pad">
<label><input type="radio" class="form-check-input" name="question{{question.qs_no}}" value="{{question.option_b}}"> B) {{ question.option_b }}</label>
</div>
<div class="radio pad">
<label><input type="radio" class="form-check-input" name="question{{question.qs_no}}" value="{{question.option_c}}"> C) {{ question.option_c }}</label>
</div>
<div class="radio pad">
<label><input type="radio" class="form-check-input" name="question{{question.qs_no}}" value="{{question.option_d}}"> D) {{ question.option_d }}</label>
</div>
</div>
{% endfor %}
</div>
</form>
Using template if/else is a straightforward approach.
{% if question.question %}
<div class="font mrl">
<h5><input type="hidden" class="form-check-input" name="question" value="{{ question.question }}">{{ question.question }}</h5>
</div>
{% else %}
<div class="font mrl">
<h5><img src="{{ question.image.url }}"></h5>
</div>
{% endif %}

Django form field is displaying uuid of the record

I am using django 2.2 and python 3.6.
I have a django modelform. I am using crispy forms to display the form in template.
The form is not displaying the value of the records. It is displaying the uuid values of the records. I need to display the record name value instead of uuid value.
models.py :
#reversion.register()
class Staff(BaseModel):
user = models.OneToOneField(
User, on_delete=models.PROTECT, db_index=True, verbose_name=_("Kullanıcı"))
photo = models.ImageField(
upload_to="staff/", null=True, blank=True, verbose_name=_("Fotoğraf"))
staff_type = models.ManyToManyField(
StaffType, verbose_name=_("Personel Tipi"))
name = models.CharField(
max_length=100, db_index=True, verbose_name=_("İsim"))
surname = models.CharField(
max_length=100, db_index=True, verbose_name=_("Soyad"))
phone = models.CharField(max_length=100, verbose_name=_("Telefon Numarası"))
email = models.EmailField(verbose_name=_("Email"), db_index=True)
address = models.TextField(verbose_name=_("Adres"))
subject = models.ForeignKey(Subject, on_delete=models.SET(
get_unknown_subject), verbose_name=_("Branş"))
gender = models.IntegerField(
choices=GENDERS, default=None, verbose_name=_("Cinsiyet"))
nationality = models.CharField(
choices=NATIONALITIES, max_length=100, verbose_name=_("Uyruk"))
blood_type = models.CharField(
choices=BLOOD_TYPES, max_length=20, verbose_name=_("Kan Grubu"))
id_no = models.CharField(max_length=100, unique=True,
verbose_name=_("Kimlik No"))
birthdate = models.DateField(verbose_name=_("Doğum Günü"))
birthplace = models.CharField(max_length=200, verbose_name=_("Doğum Yeri"))
education = models.IntegerField(
choices=EDUCATION, default=None, verbose_name=_("Eğitim"))
marital_status = models.BooleanField(
default=True, verbose_name=_("Evlilik Durumu"))
number_of_children = models.IntegerField(
verbose_name=_("Çocuk Sayısı"))
special_notes = models.TextField(
null=True, blank=True, verbose_name=_("Özel Notlar"))
registration_date = models.DateField(verbose_name=_("Kayıt Tarihi"))
foreign_language = models.ForeignKey(Language, on_delete=models.SET(
get_default_language), null=True, blank=True, verbose_name=_("Yabancı Dil"))
class Meta:
permissions = (
("list_staff", _("List Staff")),
)
ordering = ['name', 'surname']
def __unicode__(self):
return "%s %s" % (self.name, self.surname)
def save(self, *args, **kwargs):
self.name = self.name.title()
self.surname = self.surname.upper()
groups = []
for staff_type_object in self.staff_type.all():
group = Group.objects.get_or_create(name=staff_type_object.name)[0]
groups.append(group)
self.user.groups = groups
self.user.save()
super(Staff, self).save(*args, **kwargs)
views.py:
#login_required(login_url='/accounts/login/')
def personelkayit(request):
staffs = Staff.objects.values("user__username", "name", "surname", "uuid")
if request.method == 'GET':
staff_uuid = request.GET.get("staff_uuid")
if staff_uuid:
instance = get_object_or_404(Staff, uuid=staff_uuid)
form = StaffForm(instance=instance)
form.fields['username'].initial = instance.user.username
form.fields['username'].widget.attrs['readonly'] = True
else:
form = StaffForm()
return render(request, 'personelkayit.html', {'form': form, 'staffs':
staffs, 'staff_uuid': staff_uuid})
elif request.method == 'POST':
staff_uuid = request.GET.get("staff_uuid")
if staff_uuid:
instance = get_object_or_404(Staff, uuid=staff_uuid)
form = StaffForm(request.POST or None,
request.FILES or None, instance=instance)
else:
form = StaffForm(request.POST, request.FILES or None)
if form.is_valid():
password = form.cleaned_data.get("password")
re_password = form.cleaned_data.get("re_password")
staff = form.save(commit=False)
staff.user = user
staff.save()
form.save_m2m()
staff.save()
return redirect('/')
else:
return render(request, "personelkayit.html", {'form': form, 'staffs': staffs})
personelkayit.html:
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% load i18n %}
{% load staticfiles %}
{% block content %}
<br>
<table style="width: 100%">
<tr>
<td style="width: 4%"></td>
<td style="width: 92%">
<div class="block-area" id="basic">
<form role="form" method="get">
<select class="form-control input-sm m-b-10" name="staff_uuid">
<option value="" {% if not staff_uuid %} selected="selected" {% endif %} disabled="disabled">{% trans "Personel" %}</option>
{% for staff in staffs %}
<option {% if staff_uuid and staff.uuid|lower == staff_uuid|lower %}selected="selected"{% endif %} value="{{ staff.uuid }}">{{ staff.user__username }} - {{ staff.name }} {{ staff.surname }}</option>
{% endfor %}
</select>
<br />
<button type="submit" class="btn btn-sm btn-alt">{% trans "Personel Düzenle" %}</button>
<a class="btn btn-sm btn-alt" href="{% url 'personelkayit' %}">{% trans "Personel Ekle" %}</a>
<div class="modal-footer"></div>
</form>
</div>
<div class="block-area" id="basic">
<form role="form" enctype="multipart/form-data" method="post">
{% csrf_token %}
{{ form|crispy }}
<div >
<br>
<button style="background-color: #002266 !important; color: white !important" type="submit" class="btn btn-lg btn-alt"><span class="glyphicon glyphicon-floppy-disk
pull-left"></span>{% trans "Kaydet" %}</button>
</div>
</form>
<br>
</div>
</td>
<td style="width: 4%"></td>
</tr>
</table>
<script>
$( document ).ready(function() {
$( "select[name$='staff_uuid']" ).select2({
theme: "bootstrap"
});
$( "select[name$='subject']" ).select2({
theme: "bootstrap"
});
$( "select[name$='staff_type']" ).select2({
theme: "bootstrap"
});
});
</script>
{% endblock content %}
The reason this happens is because Django will render the string-representation of model objects in the form. A model is, by default rendered by the name of the type of the object, and the primary key. So a string like Subject object (...) is normal.
You can simply implement a __str__ (and for python-2.x a __unicode__) for the Subject model, to render it the way you specify:
class Subject(models.Model):
# …
def __str__(self):
return …

Categories

Resources