Relationships in Django - django-models

I have following model class set up:
class Moc(models.Model):
.....my other fields.....
def __str__(self):
return self.moc_title
def get_absolute_url(self):
return reverse('moc_content_update', kwargs={'pk': self.pk})
class Verifier(models.Model):
moc = models.ForeignKey(Moc, related_name='verifiers', on_delete=models.CASCADE, default='1')
verifier_group = models.CharField(max_length=36, blank=True, null=True)
verifier_name = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE,)
verify_due = models.DateField(blank=True, null=True)
def __str__(self):
return str(self.id)
def save(self, *args, **kwargs):
created = not self.pk
super().save(*args, **kwargs)
if created:
VerifierSignOff.objects.create(verifier=self)
class VerifierSignOff(models.Model):
verifier = models.OneToOneField(Verifier, related_name='verifiersignoff', blank=True, null=True, on_delete=models.CASCADE)
approve = models.BooleanField(default=False)
reject = models.BooleanField(default=False)
signoff_date = models.DateField(auto_now=True)
note = models.TextField(max_length=256, blank=True)
def __str__(self):
return str(self.id)
My views are stetted up to create Moc instance, add Verifiers (in total 3 users) with respective VerifierSignOff and display it on my template without any issue.
My views.py:
def verify_coordinate_view(request, pk):
moc = get_object_or_404(Moc, pk=pk)
# I guess I need to have MOC Status logic here
return render(request, 'moc/moc_content_verification.html', context={'pk':pk, 'moc':moc, })
def verifier_signoff_view(request, pk):
verifiersignoff = VerifierSignOff.objects.get(pk=pk)
form = VerifierSignForm
if request.method == 'POST':
form = VerifierSignForm(request.POST, instance=verifiersignoff)
if form.is_valid():
form.save(commit=False)
if verifiersignoff.approve is True and verifiersignoff.reject is True:
return HttpResponseForbidden('You have either APPROVE or REJECT - operation not allowed!')
else:
form.save()
return redirect('verify_coordinate', pk=verifiersignoff.verifier.moc_id)
# return redirect('index')
else:
return render(request, 'moc/verify_signoff.html', context={'verifiersignoff': verifiersignoff, 'form': form})
I am displaying everything on my template i.e. I can add/remove my users, approve/reject the record, etc.
My aim is to display my Moc instance status i.e. VERIFIED (if 3oo3 Users approve the record) or REJECTED (if anyone from 3oo3 will reject record in other words if some user rejects record becomes not valid anymore despite if other 2 users already have had it approved).
I am rendering this process on my template using of for loop:
my pseudo template:
{% for obj in moc.verifiers.all %}
<tr style="text-align: center>
<td>---my sign-off / delete user---buttons</td>
<td>{{ forloop.counter }}{{ obj.verifier_group }}</td>
<td>{{ obj.verifier_name }}</td>
<td>{{ obj.verify_due|date:'d M Y' }}</td>
<td>
<input class="form-check-input-bg" type="checkbox" value="{{ obj.verifiersignoff.approve }}" checked onclick="return false">
</td>
<td>
<input class="form-check-input-bg" type="checkbox" value="{{ obj.verifiersignoff.reject }}" onclick="return false">
</td>
<td>{{ obj.verifiersignoff.signoff_date|date:'d M Y'}}</td>
<td>{{ obj.verifiersignoff.verified_by }}</td>
<td>{{ obj.note }}</td>
{% empty %}
<td colspan="8" style="WIDTH: 130px">No verifiers assigned yet...</td>
</tr>
{% endfor %}
I am able to display individual for loop object approve/reject status individually in my template, however I want to display consolidated STATUS as per my above description i.e. something like:
MOC STATUS: {{?????? I don't know how I can generate this variable in my logic ?????}}
My template snippet:

Related

How can i filter model field ForeignKey group django

i get All Profiles
i need just Profile of my group
How can I filter the options shown for a ForeignKey field in a Model Form?
In that form I want to show only the profiles in the group , so the user can only get a profile for the new user
class Profile_user(models.Model):
group = models.ForeignKey (Group, null=True ,on_delete=models.CASCADE)
name_Profile= models.CharField(max_length=200, null=True)
class Account(AbstractBaseUser , PermissionsMixin):
Profile = models.ForeignKey(Profile_user,null= True, on_delete=models.CASCADE)
email = models.EmailField(max_length=60, unique=True)
username = models.CharField(max_length=30, unique=True)
class Registration_Form_Users(UserCreationForm):
class Meta:
model = Account
fields = ('email', 'username', 'password1', 'password2','Profile',)
form = Registration_Form_Users()
if request.method == 'POST':
form = Registration_Form_Users(request.POST)
form = Registration_Form_Users()
if request.method == 'POST':
form = Registration_Form_Users(request.POST)
<div class="col-md-6 mb-4">
<h6>Select Profile User</h6>
<fieldset class="form-group">
<select class="form-select" name="Profile"
<option ></option>
{% for item in form.Profile %}
{{item}}
{% endfor %}
</select>
</fieldset>

Why the NO Null constrained error keeps raising when trying to comment

I am trying to comment in a room but anytime I commented a Non NUll constrained error raised and I cannot find the problem.
The models are as follows:
class Room(models.Model):
host = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
topic = models.ForeignKey(Topic, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-updated', '-created']
def __str__(self):
return self.name
class Message(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
room = models.ForeignKey(Room, on_delete=models.CASCADE)
body = models.TextField()
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.body[0:50]
The views is as follows:
def room(request, pk):
room = Room.objects.get(id=pk)
room_messages = room.message_set.all().order_by('-created')
if request.method == 'POST':
message = Message.objects.create(
user=request.user,
room=room,
body=request.POST.get('body')
)
return redirect('room', pk=room.id)
context = {
'room': room, 'room_messages':room_messages
}
return render(request, 'base/room.html', context)
The html:
{% if request.user.is_authenticated %}
<div class="comment-form">
<form method="POST" action="">
{% csrf_token %}
<!-- {{form}} -->
<input type="text" name="comment" placeholder="Write your message here..."/>
</form>
</div>
{% endif %}
{% endblock content %}
Thank you. I found out that in the html I've assigned "comment" instead of "body" to the name=''" in the input tag.

How to show choice field in template form

I want to show the Django choice field from Model on the HTML template like in the following picture. I can't see anything after doing this code.
models.py
class Author(models.Model):
TITLE_CHOICES = [
('MR', 'Mr.'),
('MRS', 'Mrs.'),
('MS', 'Ms.'),
]
title = models.CharField(max_length=3, choices=TITLE_CHOICES)
views.py
def AuthorView(request):
form = Author(request.POST or None)
title = Author.objects.all()
context = {
"form": form,
"ttile": title,
}
if form.is_valid():
form.save()
return render(request, 'index.html')
return render(request, 'index.html', context)
index.html
<select name="confirm_type" id="confirm_type">
{% for object in ttile %}
<option value="by_email"> {{ object }} </option>
{% endfor %}
</select>

WTForms not working on Google App Engine 1.6.1 & Python 2.7

I'm new at GAE and all that python stuff, so question might be stupid at last.)
I have model:
from google.appengine.ext import db
class Task(db.Model):
name = db.StringProperty()
summary = db.StringProperty(multiline=True)
and I want to auto generate form, so:
import webapp2
import jinja2
import os
from wtforms.ext.appengine.db import model_form
from Tasks.model import Task
jinja_environment = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__) + '/../templates/admin'))
class AddTaskPage(webapp2.RequestHandler):
def get(self):
AddForm = model_form(Task)
template_values = {
'form_self_link': self.request.path,
'form_content': AddForm
}
template = jinja_environment.get_template('add_task.html')
self.response.out.write(template.render(template_values))
add_task.html template:
<form method="POST" action="{{form_self_link}}">
{{form_content}}
<input type="submit" value="Add">
</form>
And the most confusing is output – 
<form method="POST" action="/admin/tasks/add">
<class 'wtforms.ext.appengine.db.TaskForm'>
<input type="submit" value="Добавить">
</form>
There is NO form's elements, there is just very strange <class 'wtforms.ext.appengine.db.TaskForm'> stuff.
I use GAE 1.6.1, python 2.7.2, jinja 2.6 (bundled with GAE), WTForms 0.6.3 (latest)
Could you please help?
UPDATE:
I've used instruction bundled with class and it is not working:
from google.appengine.ext import db
from tipfy.ext.model.form import model_form
# Define an example model and add a record.
class Contact(db.Model):
name = db.StringProperty(required=True)
city = db.StringProperty()
age = db.IntegerProperty(required=True)
is_admin = db.BooleanProperty(default=False)
new_entity = Contact(key_name='test', name='Test Name', age=17)
new_entity.put()
# Generate a form based on the model.
ContactForm = model_form(Contact)
# Get a form populated with entity data.
entity = Contact.get_by_key_name('test')
form = ContactForm(obj=entity)
The only strange moment is "from tipfy.ext.model.form import model_form" string, but I think it is just an error in docs.
UPDATE 2
Well I managed to get it work and may be I missed something, seems like there is no feature "auto print form" in WTForm. So it works now like that:
class AddTaskPage(webapp2.RequestHandler):
def get(self):
AddForm = model_form(Task)()
template_values = {
'form_self_link': self.request.path,
'form_name_field': AddForm.name
}
template = jinja_environment.get_template('add_task.html')
self.response.out.write(template.render(template_values))
And prints out
<form method="POST" action="/admin/tasks/add">
<input id="name" name="name" type="text" value="">
<input type="submit" value="Добавить">
</form>
Well... seems like the only option is to do something like in future (taken from docs)
<form method="POST" action="/...">
<div>{{ form.username.label }}: {{ form.username(class="css_class") }}</div>
<div>{{ form.password.label }}: {{ form.password() }}</div>
<!-- and so on .... -->
</form>
Is it really no any auto-generate and auto-print form libraries for GAE with Python 2.7?(
LAST UPDATE
Well... I found one option to get it work and render all form elements:
class AddTaskPage(webapp2.RequestHandler):
def get(self):
addForm = model_form(Task)()
template_values = {
'form_self_link': self.request.path,
'form': addForm
}
template = jinja_environment.get_template('add_task.html')
self.response.out.write(template.render(template_values))
def post(self):
addForm = model_form(Task)(self.request.POST)
template_values = {
'form_self_link': self.request.path,
'form': addForm
}
template = jinja_environment.get_template('add_task.html')
self.response.out.write(template.render(template_values))
In template:
{% for field in form %}
<tr>
<th>{{ field.label }}</th>
<td>{{ field }}</td>
</tr>
{% endfor %}
Looks not so bad .)
I think you have to pass AddForm.content as a template value (instead of AddForm)
template_values = {
'form_self_link': self.request.path,
'form_content': AddForm**.content**
}
UPDATE
found this in the docs
(http://wtforms.simplecodes.com/docs/0.6.1/ext.html#wtforms.ext.appengine.db.model_form)
wtforms.ext.appengine.db.model_form(model)
Creates and returns a dynamic wtforms.Form class for a given db.Model class. The form class can be used as it is or serve as a base for extended form classes...
So what you are passing into the template is the class, not an instance of it.
AddForm = model_form(Task)()

Add or Update object from a form GAE python

I try to create a class which will add data from a form to a db.model, but my problem is that when I will try to add an existing book, I want to update the copies and not to add a new object. I really try to find an answer, I read books for programming in GAE, but I find nothing for my problem.
Thank you in advance and I will really appreciate if someone answer with a sample code and not with just a command ( eg try get_by_id()).
Here is a part of my source
class Book(db.Model):
book_id = db.IntegerProperty()
title = db.StringProperty()
author = db.StringProperty()
copies = db.IntegerProperty()
isbn = db.IntegerProperty()
copyright_date = db.StringProperty()
category = db.StringProperty()
comments = db.StringProperty()
class Add(webapp.RequestHandler): #Form to input data
def get(self):
self.response.out.write("""
<html>
<body>
<form action="/sign" method="post">
<table border="0">
<tr>
<td>ISBN:</td> <td><input type="text" name="isbn"</td>
</tr>
<tr>
<td>Title:</td> <td><input type="text" name="title"</td>
</tr>
<tr>
<td>Author:</td> <td><input type="text" name="author"</td>
</tr>
<tr>
<td>Copies:</td> <td><input type="text" name="copies"</td>
</tr>
<tr>
<td>Copyright Date:</td> <td><input type="text" name="copyright_date"</td>
</tr>
<tr>
<td><div>Category:</td> <td><select>
<option name="category" value="adventure">Adventure</option>
<option name="category" value="comedy">Comedy</option>
<option name="category" value="dramatic">Dramatic</option>
<option name="category" value="mystery">Mystery</option>
<option name="category" value="science_fiction">Science Fiction</option></select></td>
</tr>
<tr><td>Comments:</td></tr></table>
<div><textarea name="comments" rows="5" cols="40" value="Add your comments here"></textarea></div>
<div><input type="submit" value="Add Book">
<input type="reset" value="Reset"></div>
</form>
</body>
</html>""")
class Guestbook(webapp.RequestHandler):
def post(self):
book = Book()
book.isbn = int(self.request.get('isbn'))
book.title = self.request.get('title')
book.author = self.request.get('author')
book.category = self.request.get('category')
book.copies = int(self.request.get('copies'))
book.copyright_date = self.request.get('copyright_date')
book.put()
class Stock(webapp.RequestHandler):
def get(self): #Retrieve all data from DataBase (Here is the StockHouse)
Book = db.GqlQuery("SELECT * FROM Book ")
for book in Book:
print book.book_id, book.isbn, book.title, book.author, book.category, book.copyright_date, book.copies, book.comments
in order to update an existing entry you'll need a different handler that will take the post arguments as well as the id or key of the entity to update. Usually this is in the url, e.g:
POST /updateentity/id
and then in the handler:
def get(self, id):
existing = Model.get_by_id(long(id))
model.field = self.request.get("field")
model.put()
You can use get_or_insert Model method. Also see this question.

Resources