Customize form field according to other field - python

Please give me advice for my following question. I have added corresponding script at the bottom of this sentence. Thank you in advance!!!
What I want to do: Customize form field according to the target field specified in the database as shown in following image.
Current situation
All the radio buttons in Ecms table are listed in one column
html file
{% extends "base.html" %}
(% load widget_tweaks %}
{% block content %}
<form method="post" enctype="multipart/form-data">
<h4 style="margin-top: 0">Project Upload</h4>
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{hidden}}
{% endfor %}
{% for field in form.visible_fields %}
<div class="form-group">
<label for="{{field.id_for_label}}">{{field.label}}</label>
{{field}}
</div>
{% endfor %}
<button type="submit">Upload</button>
</form>
{% endblock %}
Model.py(parent)
class html(models.Model):
project = models.CharField(max_length=50, blank=True)
version = models.IntegerField(default=0)
ecms=models.ManyToManyField(ecm, blank=True)
diff = models.TextField(blank=True)
PROGRAM_CHOICES = (
('Office', 'General office'),
('Residential', 'Residential'),
('Retail', 'Retail'),
('Restaurant', 'Restaurant'),
('Grocery', 'Grocery store'),
('Medilcal', 'Medilcal office'),
('Research', 'R&D or laboratory'),
('Hotel', 'Hotel'),
('Daycare', 'Daycare'),
('K-12', 'Educational,K-12'),
('Postsecondary', 'Educational,postsecondary'),
('Airport', 'Airport'),
('DataCenter','Data Center'),
('DistributionCenter','Distribution center,warehouse')
)
program = models.CharField(max_length=20, choices=PROGRAM_CHOICES, default='Retail')
LOCATION_CHOICES = (
('Beijing', 'Beijing'),
('China', 'China'),
('Hong Kong', 'Hong Kong'),
('Japan', 'Japan'),
('Shanghai', 'Shanghai'),
('Shenzhen', 'Shenzhen'),
('Taiwan', 'Taiwan'),
('USA', 'United States')
)
location = models.CharField(max_length=15, choices=LOCATION_CHOICES, default="Hong Kong")
CERTIFICATE_CHOICES = (
('LEED_v3', 'LEED_v3'),
('LEED_v4', 'LEED_v4'),
('BEAM+', 'BEAM+'),
('WELL', 'WELL'),
('No certificate','No certificate')
)
certificate = models.CharField(max_length=20, choices=CERTIFICATE_CHOICES, default='BEAM+')
user = models.CharField(max_length=20, default='test')
html = models.FileField(upload_to=dir_path)
uploaded_at = models.DateTimeField(auto_now_add=True)
Model.py
class ecm(models.Model):
name = models.CharField(max_length=50, blank=True)
TARGET_CHOICES = (
('Heating', 'Heating'),
('Cooling', 'Cooling'),
('Fan', 'Fan'),
('Lighting', 'Lighting'),
('Equipment', 'Equipment'),
('Renewable','Renewable Energy'),
('Hot Water','Hot Water System'),
('Others', 'Others'),
)
target=models.CharField(max_length=20, choices=TARGET_CHOICES, default='Others')
description = models.TextField(blank=True)
link=models.URLField(blank=True)
def __str__(self):
return self.name
views.py
def model_form_upload(request):
if request.method == 'POST':
if form.is_valid():
newhtml = form.save()
newhtml.save()
else:
form = DocumentForm()
return render(request, 'model_form_upload.html', {'form': form})

You should render your fields manually, not iterate over them. I suggest wrapping each of the columns you want into a div and setting width to the resulting divs.

Related

IntegrityError a NOT NULL constraint failed : Submit a form through django

I'd like to make a POST REQUEST with an existing HTML FORM, to store it in a database, but everytime I tried to submit data through the form, it gives me the following error
By the way I'm doing this following those post:
Django form using HTML template
MultiValueDictKeyError generated in Django after POST request on login page
Registro.html
{% extends "RegistrarProyecto/layout.html" %}
{% block title %} {% endblock %}
{% block content %}
<h1>Crear Usuario</h1>
<form class="CrearUsuario" action="{% url 'registro' %}" method="POST">
{% csrf_token %}
<input type="text",name="NombreProyecto", placeholder="Nombre del Proyecto" >
<br>
<br>
<input type ="text", name="ResponsableProyecto", placeholder ="Responsable del proyecto">
<br>
<br>
<textarea name="DescripcionProyecto", rows="4", cols="50"></textarea>
<br>
<br>
<input type="submit" value="Registrar">
</form>
<br>
Ir a Bienvenido
{% endblock %}
views.py
def registro(request):
if request.method == 'POST':
NombreProyecto = request.POST.get('NombreProyecto')
ResponsableProyecto = request.POST.get('ResponsableProyecto')
DescripcionProyecto = request.POST.get('DescripcionProyecto')
Proyecto.objects.create(NombreProyecto=NombreProyecto,ResponsableProyecto=ResponsableProyecto,DescripcionProyecto=DescripcionProyecto)
return redirect("RegistrarProyecto/index.html")
return render(request, 'RegistrarProyecto/Registro.html')
models.py
from django.db import models
# Create your models here.
class Proyecto(models.Model):
NombreProyecto = models.CharField(max_length = 64)
ResponsableProyecto = models.CharField(max_length= 64)
DescripcionProyecto = models.CharField(max_length = 64)
def __str__(self):
return f"{self.NombreProyecto}"
class Evaluador(models.Model):
NombreEvaluador = models.CharField(max_length=64)
Proyecto = models.ManyToManyField(Proyecto, blank=True, related_name="Evaluador")
def __str__(self):
return f"{self.NombreEvaluador} {self.Proyecto}"
urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("Registro", views.registro, name="registro")
]
it is this line:
<input type="text",name="NombreProyecto", placeholder="Nombre del Proyecto" >
change it to:
<input type="text", name="NombreProyecto", placeholder="Nombre del Proyecto" >
I'd suggest two things. 1. Either you set your model field as null-able that even it doesn't get a value for one of those fields it will still be saved. For example:
class Proyecto(models.Model):
NombreProyecto = models.CharField(max_length=64, null=True, blank=True)
ResponsableProyecto = models.CharField(max_length=64, null=True, blank=True)
DescripcionProyecto = models.CharField(max_length=64, null=True, blank=True)
def __str__(self):
return f"{self.NombreProyecto}"
Set your html input and textarea fields with the required attribute required. That values are passed for all fields.

How to fix Order matching query doesn't exist in Django?

Unable to delete an object:
HViews is as follows
def deleteorder(request, pk):
order = Order.object.get(id=pk)
if request.method == 'POST':
order.delete()
return redirect()
context = {'item':order}
return render(request,'accounts/delet.html', context)
And
Urls.py is as
path('delete_order/<str:pk>/', views.deleteorder, name= 'delete_order')
models.py
class Order(models.Model):
STATUS = ( (' Pending', 'Pending'), ('Out for Delivery ', 'Out for Delivery '), ('Delivered ', 'Delivered ') , )
customers = models.ForeignKey(Customer, null=True, on_delete= models.SET_NULL)
products = models.ForeignKey( Product, null=True, on_delete = models.SET_NULL)
created_date = models.DateTimeField(auto_now_add=True, null=True)
status = models.CharField(max_length=100, null=True, choices = STATUS)
def __str__(self):
return self.products.name
Try this and see it it work for you. How to delete an order by ID or pk. For example you have order views like this:
def order_views(request):
my_order = OrderItem.objects.all()
#you can also filter through your order
context = {'my_order': my_order}
{% for order in my_order %}
#Your code here
Delete
{% endfor %}
def deleteorder(request, pk):
order = Order.object.get(id=pk)
order.delete()
return redirect()
path('delete_order/<pk>/', views.deleteorder, name= 'delete_order')
or
path('delete_order/<int:pk>/', views.deleteorder, name= 'delete_order')
Remember to pass the correct Order context with the pk in template, so you don't get reverse not found.
my code where POST is being called is given below.
{% extends 'accounts/main.html' %}
{% load static %}
{% block content %}
<form action="" method="POST">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{{form}}
<hr>
{% endfor %}
<input type="submit" name="Submit">
</form>
{% endblock %}

How to check existence of a record in a model from current authenticated user in Django template?

Code below checks whether a user added a product in cart or not. If it is added to cart by this current user it should show remove from cart button else it should show a simple form to add product in cart.
{% for ordereditem in item.ordereditems_set.all %}
{% if ordereditem.quantity > 0 and ordereditem.user.username == user.username %}
Remove from cart
{% elif not ordereditem %} # here!
<!-- else if there is no record of 'ordereditem' from current user show this form to add it to cart-->
<form class="d-flex justify-content-left" method="POST" action="{{ item.get_add_to_cart_url }}">
{% csrf_token %}
<input type="number" name="number" value="1">
<input type="submit" value="Add to cart">
</form>
{% endif %}
{% endfor %}
the problem lies here {% elif not ordereditem %} it seems like my current if statement doesn't meet the condition I expect. I tried using {% else %} but it still shows the form even after adding product to cart.
This is how models look like:
class Item(models.Model):
title = models.CharField(max_length=100)
price = models.FloatField()
discount_price = models.DecimalField(max_digits=5,
decimal_places=2, verbose_name='Discount', null=True, blank=True)
image = models.ImageField(upload_to='products/%Y/%m/%d/')
image_cover = models.ImageField(upload_to='products/%Y/%m/%d/')
description = models.TextField()
slug = models.SlugField(max_length=150, blank=True, null=True)
category = models.CharField(max_length=15, choices=CATEGORY_CHOICE)
label = models.CharField(max_length=10, choices=LABEL_CHOICE)
associated_items = models.ManyToManyField("self", blank=True, null=True)
class OrderedItems(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
ordered = models.BooleanField(default=False)
class Order(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
items = models.ManyToManyField(OrderedItems)
start_date = models.DateTimeField(auto_now_add=True)
ordered_date = models.DateTimeField()
ordered = models.BooleanField(default=False)
Here is the github link. Thank You
You need {% empty %} here:
{% for ordereditem in item.ordereditems_set.all %}
...
{% empty %}
No items
{% endfor %}

Django - objects.all() shows nothing

I'm trying to get a list of objects in Django from a model.
I just want to get the list of 'dht node' from the request user, but it shows nothing in the html file (as if the list was empty). The user that I'm using has 2 'dht nodes' and they're shown in the django admin.
I don't know what is wrong, because if I use the instruction "member.dht.create(...)" in the views function and a create a new 'dht node' like this, this is shown. Only 'dht nodes' that I enter by form do not show. Can be the form?
Thanks a lot, Here's my code:
Models.py
class Node(models.Model):
name = models.CharField(primary_key=True, null=False, max_length= 50)
description= models.CharField(default=None, null=False, max_length= 250)
topic=models.CharField(default=None, null=False, max_length= 50, unique=True)
def __unicode__(self):
return self.name
class dht(Node):
temp = models.IntegerField(default=None, null=True)
hum = models.IntegerField(default=None, null=True)
class UserProfile(User):
uid = models.CharField(default=None, null=False, max_length= 250)
dht = models.ManyToManyField(dht, blank=True)
def __unicode__(self):
return self.user.username
Views.py -dht list-
#login_required(login_url = '/web/login')
def listDhtSensor(request):
member = request.user.userprofile
list = member.dht.all()
return render(request, 'web/listDhtSensor.html', {'list':list})
Html -listDhtSensor.html-
{% block content %}
{% for dht in list %}
{{ dht.name }}
{{ dht.topic }}
{% endfor %}
{% endblock %}
Forms.py
class newDHTSensorForm(forms.ModelForm):
class Meta:
model = dht
field = ['name',
'description',
'topic',]
labels = {'name': 'Name' ,
'description': 'Description',
'topic': 'Topic',}
exclude = ['temp', 'hum']
Views.py -dht form-
#login_required(login_url = '/web/login')
def newDHTSensor(request):
if request.method == "POST":
form = newDHTSensorForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.save()
return redirect('/web/dhtDetail')
else:
form = newDHTSensorForm()
return render(request, 'web/newDhtSensor.html', {'form': form})
Html -newDhtSensor.html-
{% block content %}
<div class="boxReg">
<form method="post">
{% csrf_token %}
<h2>{{ form.name.errors.as_text }}</h2>
<p><label for="id_name">Name:</label> <input class="barraForm" type="text" name="name" maxlength="150" autofocus="" required="" id="id_name"></p>
<p><label for="id_description">Description:</label> <input class="barraForm" type="text" name="description" maxlength="150" id="id_description"></p>
<h2>{{ form.topic.errors.as_text }}</h2>
<p><label for="id_topic">Topic:</label> <input class="barraForm" type="text" name="topic" maxlength="254" id="id_topic"></p>
<div class="boxButtonReg">
<button class="buttonReg" type="submit">Save</button>
</div>
</form>
</div>
{% endblock %}
It shows nothing because you did not link you dht objects to that UserProfile, so if you later query for the dhts for that UserProfile, evidently the list is empty. You should add it to the dht relation, like:
#login_required(login_url = '/web/login')
def newDHTSensor(request):
if request.method == "POST":
form = newDHTSensorForm(request.POST)
if form.is_valid():
post = form.save()
request.user.userprofile.dht.add(post)
return redirect('/web/dhtDetail')
else:
form = newDHTSensorForm()
return render(request, 'web/newDhtSensor.html', {'form': form})
Note that you first need to save the post, so you should omit the commit=False aprameter.

Unable to render ForeignKey fields in my template

I'm making a comment system for my django app and i've been told it's best to make a seperate model for comment-voting. So i've done that and here's my models.py:
class Comment(models.Model):
user = models.ForeignKey(User, default=1)
destination = models.CharField(default='1', max_length=12, blank=True)
author = models.CharField(max_length=120, blank=True)
comment_id = models.IntegerField(default=1)
parent_id = models.IntegerField(default=0)
comment_text = models.TextField(max_length=350, blank=True)
timestamp = models.DateTimeField(default=timezone.now, blank=True)
def __str__(self):
return self.comment_text
class CommentScore(models.Model):
user = models.ForeignKey(User, default=1)
comment = models.ForeignKey(Comment, related_name='score')
upvotes = models.IntegerField(default=0)
downvotes = models.IntegerField(default=0)
def __str__(self):
return str(self.comment)
Here's my views.py where the comments are created:
def article(request, category, id):
name = resolve(request.path).kwargs['category']
for a, b in CATEGORY_CHOICES:
if b == name:
name = a
instance = get_object_or_404(Post, id=id, category=name)
allauth_login = LoginForm(request.POST or None)
allauth_signup = SignupForm(request.POST or None)
#comments
comment = CommentForm(request.POST or None)
ajax_comment = request.POST.get('text')
comment_length = len(str(ajax_comment))
comment_list = Comment.objects.filter(destination=id)
score = CommentScore.objects.filter(comment=comment_list)
if request.is_ajax():
if comment.is_valid():
comment = Comment.objects.create(comment_text=ajax_comment, author=str(request.user), destination=id)
print(comment)
comment.save()
score = CommentScore.objects.create(comment=comment)
score.save()
username = str(request.user)
return JsonResponse({'text': ajax_comment, 'text_length': comment_length, 'username': username})
else:
print(comment.errors)
context = {
'score': score,
'comment_list': comment_list,
'comment': comment,
'instance': instance,
'allauth_login': allauth_login,
'allauth_signup': allauth_signup
}
return render(request, 'article.html', context)
So the comment works fine, but as you can see a couple lines later i'm trying to then create a CommentScore instance to match with the comment. In my template, I've rendered each comment and it's fields (comment_text, author etc), but I want to render the upvotes field associated with that comment. How would I do this?
template
{% for i in comment_list %}
<div class='comment_div'>
<h3>{{ i.author }}</h3>
<p>{{ i.comment_text }}</p><br>
</div>
{% endfor %}
forms.py
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = [
'comment_text',
'id',
'author',
'destination',
]
I've already tried the following and they haven't worked;
{% for i in comment_list %}
<div class='comment_div'>
<h3>{{ i.author }}</h3>
<p>{{ i.comment_text }}</p><br>
{% for i in comment_list.score_set.all %}
{{ i.upvotes }} #renders nothing
{% endfor %}
</div>
{% endfor %}
{% for i in comment_list %}
<div class='comment_div'>
<h3>{{ i.author }}</h3>
<p>{{ i.comment_text }}</p><br>
{% for j in i.score %}
{{ j.upvotes }} #Error: 'RelatedManager' object is not iterable
{% endfor %}
</div>
{% endfor %}
Having a lot of trouble so help is appreciated.
Changing "i.score" to "i.score.all" resolves the problem as the RelatedManaager error usually happens when you are trying to iterate over the manager and not the objects selected by that manager. - Solved by #joe-j
So it works now but if someone could explain the 2nd line of this syntax that would be great:
comment_list = Comment.objects.filter(destination=id)
score = CommentScore.objects.filter(comment=comment_list)
What exactly is happening when I assign comment=comment_list here? I copied this code from someone else but i'm still abit unsure how it's working.

Categories