Django Grabbing Value field from POST - django

I have an app that let users create blogs and allow other users to comment on each other blogs.The Problem is .In order to create a comment object , I require the blog id and text . I can grab the text data via post but I'm having trouble getting the blog id from POST and the only way I can think of getting it is via value field in the form
How can I grab the value field from POST?
My models
class Blog(models.Model):
user = models.ForeignKey(User)
name = models.CharField(max_length=100)
created = models.DateTimeField(auto_now_add=True)
description = models.TextField()
class BlogComment(models.Model):
created = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User)
body = models.TextField()
blog = models.ForeignKey(Blog)
my forms.py
class BlogCommentForm(forms.ModelForm):
text = forms.CharField(required=False)
class Meta:
model = BlogComment
fields = ()
<form method ="POST"> {% csrf_token %}
<input type = "hidden" name="d" value= "blog.id" />
{{form}}
</form>
My views
def Blogs(request,blog_id):
form = BlogCommentForm(request.POST)
if request.method == "POST":
if form.is_valid():
text = form.cleaned_data['text']
value = form.cleaned_data['value']
form = BlogCommentForm()
blog.objects.get(pk=blog_id)
comment = BlogComment.objects.filter(blog=blog)
return render(request,'blogcomment.html',{'comment':comment,'form':form})

request.POST['d']
or to avoid raising an Exception if it's not there use
request.POST.get('d', False)

You can always get the blog id from ?= parameter in url.
When user goes to comment someone's blog the url might be http://yoursite.com/blog/id/comment or http://yoursite.com/blog/comment?blogid=12345.

Related

Django: Add a new value to ModelChoiceField

I have a ModelChoiceField in a form that uses a TextInput widget. I want to be able to select a value from the database or add new entries to the database with this input. If the value is not already in the database, I get an error on the form that says "Select a valid choice. That choice is not one of the available choices."
Model
class FeedCategory(models.Model):
category = models.CharField(max_length=255, unique=True)
class RssFeed(models.Model):
category = models.ForeignKey(FeedCategory, null=True, on_delete=models.SET_NULL)
name = models.CharField(max_length=255)
feed = models.URLField()
Form
class RssForm(forms.Form):
name = forms.CharField()
feed = forms.URLField()
category = forms.ModelChoiceField(queryset=FeedCategory.objects.all(), to_field_name='category', widget=forms.TextInput())
def clean(self):
cleaned_data = super().clean()
????
Views
class RssCreateView(FormView):
template_name = 'dashboard/rss_feed_form.html'
form_class = RssForm
success_url = '/dashboard/'
def form_valid(self, form):
name = form.cleaned_data['name']
feed = form.cleaned_data['feed']
category = form.cleaned_data['category']
rss_obj = RssFeed(category=category, name=name, feed=feed)
rss_obj.save()
return super().form_valid(form)
Template
<form method="post">
{%csrf_token%}
{{form|crispy}}
<button type="submit">Save</button>
</form>
It might help you what I am using:
category = models.ForeignKey("General.entity",verbose_name='Category', db_column="CategoryEntityRef", null=False, blank=False)
so, what I am doing with this is creating a field that points to an existing category that exists in another table. It will display it as a dropdown box. However using this method will allow me to have the option to add another Category:

Django - Dynamic filter Foreign Key choices on previοus user choice

I'm building an app for personnel. Someone belongs in a company, which have different departments. A department from one company may have the same name with the department of another company.
The models:
class Company(models.Model):
COMPANIES = (('Comp1', 'Comp1'), ('Comp2', 'Comp2'), ('Comp3', 'Comp3'),)
name = models.CharField(primary_key=True, max_length=5, choices=COMPANIES)
def __str__(self):
return self.name
class Departments(models.Model):
name = models.CharField(max_length=10)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
def __str__(self):
return self.name
class Personel(models.Model):
name = models.IntegerField(primary_key=True, unique=True)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
department = models.ForeignKey(Departments, on_delete=models.CASCADE)
The (very basic) form:
class PersonelForm(forms.ModelForm):
class Meta:
model = Personel
fields = ['name', 'company', 'department']
Companies and Departments are managed from the admin page.
The view:
def new_personel(request):
template = 'TestApp/new_personel.html'
form = PersonelForm(request.POST or None)
if form.is_valid():
form.save()
return HttpResponseRedirect('/thanks/')
context = {
'form': form
}
return render(request, template, context)
The template:
<form method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
With the current code, in the department select field are shown all the departments from all companies in the database. What I'm trying to achieve is when the user selects the company, the department select field dynamically being filled with the departments from the selected company.
All the solutions I managed to find requires the company being selected before the form loads (e.g. set company in a form and continue to another form for the rest fields, use of ModelChoiceField, use of limit_choices_to and define init).
Is there a way to achieve this through Django or with the use of JavaScript in the html?
(of course more than welcome a solution that can do that in the admin page also)
You could use the ModelSelect2 widget from django-autocomplete-light.
You would define a form
from dal import autocomplete
class PersonelForm(forms.ModelForm):
department = forms.ModelChoiceField(queryset=Department.objects.all(),
widget=autocomplete.ModelSelect2(url='department-autocomplete', forward=('company', )))
Then you need to define the department-autocomplete URL view
class DepartmentAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
queryset = Department.objects
company = self.forwarded.get('vzw')
if company:
queryset = queryset.filter(company__pk=company)
return queryset.filter(name__icontains=self.q) if self.q else queryset
The self.q in this view is the query that you're typing in the form. Also don't forget to import the necessary javascript and css as stated in the documentation.

How to get current item in Django

In my Django project I have catalog of products, there is how its look like in models.py:
class Category(models.Model):
category = models.CharField(max_length=15)
description = models.CharField(max_length = 1000)
class Product(models.Model):
name = models.CharField(max_length=15)
description = models.CharField(max_length=1000)
category = models.ForeignKey(Category)
This is product detail view.
def ProductDetailView(request, pk):
productdetail = get_object_or_404(Product, pk=pk)
return render(request, 'product/detail.html', {'productdetail':productdetail})
And this is urls.py for product detail view:
url(r'^(?P<pk>[0-9]+)/$', views.ProductDetailView, name='detail'),
Now I need to add an order button on product detail page. When user click on this button, the data with the order have to save to the database, so i made a new model:
class Order(models.Model):
order_id = models.AutoField(primary_key=True, unique=True)
customer_name = models.CharField(max_length=20)
email = models.CharField(max_length=50)
product = models.ForeignKey(Product)
All datas for this model i take from the form, but i don't know how to get current product field. I will be thankful if you will help me with it.
You can add current item ID to HTML (by template tags). For example as hidden form field:
<input id="id_current_item_id" name="current_item_id" type="hidden"
value="{{ current_item.id }}"/>
Try
<input name="prouct_id" id="id_product" type="hidden" value="{{product.id}}">
and submit the order form. You will get product id in view.

ModelForm with OneToOneField in Django

I have two models in Django that are related with a OneToOneField (PrinterProfile and PrinterAdress).
I am trying to do a form with PrinterProfileForm, but for some reason it does NOT pass the PrinterAddress fields into the form (it's not rendered by Django "magic" in the template).
What should I do so that my PrinterProfileForm include as well the fields from PrinterAddress (its related OneToOneField)?
Thanks a lot
class PrinterProfile(TimeStampedModel):
user = models.OneToOneField(User)
phone_number = models.CharField(max_length=120, null=False, blank=False)
additional_notes = models.TextField()
delivery = models.BooleanField(default=False)
pickup = models.BooleanField(default=True)
# The main address of the profile, it will be where are located all the printers.
class PrinterAddress(TimeStampedModel):
printer_profile = models.OneToOneField(PrinterProfile)
formatted_address = models.CharField(max_length=200, null=True)
latitude = models.DecimalField(max_digits=25, decimal_places=20) # NEED TO CHECK HERE THE PRECISION NEEDED.
longitude = models.DecimalField(max_digits=25, decimal_places=20) # NEED TO CHECK HERE THE PRECISION NEEDED.
point = models.PointField(srid=4326)
def __unicode__(self, ):
return self.user.username
class PrinterProfileForm(forms.ModelForm):
class Meta:
model = PrinterProfile
exclude = ['user']
You have to create second form for PrinterAddress and handle both forms in you view:
if all((profile_form.is_valid(), address_form.is_valid())):
profile = profile_form.save()
address = address_form.save(commit=False)
address.printer_profile = profile
address.save()
Of course in the template you need to show both forms under one <form> tag :-)
<form action="" method="post">
{% csrf_token %}
{{ profile_form }}
{{ address_form }}
</form>
Complementing the accepted answer:
If you have custom clean methods, you need to add a try/except case. For the example presented if address had a clean() method to validate something you needed to change it to:
def clean(self):
try:
printer_profile = self.printer_profile
except ObjectDoesNotExist:
pass
else:
...code to validate address...

Django add textfield on click

I am writing a django recipe website and have a question about JSON Field and forms
I am trying to write the create recipe function for the site and wanted to do two things:
I want to add text fields on mouse click similarly to adding attachments with e-mails. I want to use JSONField to do so (unless picklefield is better)
i want the user to be able to edit the recipe in one textfield.
I was hoping i could pack all of the steps into one text field and allow them to edit that field and then unpack them back into the steps. otherwise it might get confusing for the user to have to edit each individual step.
here are my models from the django project:
class Cookbook(models.Model):
def __unicode__(self):
return self.name
name = models.CharField(max_length=50)
pub_date = models.DateTimeField('date published')
user = models.ForeignKey(User, related_name='cookbooks')
recipes = models.ManyToManyField('Recipe', related_name = 'cookbooks')
class Recipe(models.Model):
def __unicode__(self):
return self.name
original_cookbook = models.ForeignKey(Cookbook)
name = models.CharField(max_length=200)
author = models.CharField(max_length= 100)
picture = models.ImageField(upload_to = 'Downloads', blank=True)
pub_date = models.DateTimeField('date published', auto_now_add=True, blank=True)
ingredients = JSONField()
steps = JSONField()
prep_time = models.IntegerField()
Here is the view in which I create a new recipe. Right now I am unsure how to use the JSONField in my view.
I found this link but it states "Finally, I'm not sure how to interact with forms yet, so that realm is a bit murky." Seeing that I am using a form, has this been resolved?
def createrecipe(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/index/')
else:
if request.method == 'POST':
form = RecipeForm(request.POST)
if form.is_valid():
recipe = form.save(commit=False)
recipe.original_cookbook = request.user.cookbooks.all()[0]
recipe.pub_date = datetime.datetime.now()
recipe.save()
user = request.user
cookbooks = user.cookbooks
cookbook = cookbooks.all()[0]
cookbook.recipes.add(recipe)
return HttpResponseRedirect('/account')
else:
form = RecipeForm()
return render_to_response('cookbook/createrecipe.html',
{'form':form},
context_instance=RequestContext(request))
here is the createrecpe.html block content:
{% block content %}
<form action="." method="POST">
<table>
{% csrf_token %}
{{ form.as_table }}
</table>
<p><input type="submit" value="Submit"></p>
</form>
{% endblock %}
I am having a hard time bridging the gap between the JSONField model and the view to display/enter text into the JSON field. I also am confused how to display the jsonfield in a template.
thank you for any help this has really been discouraging me,
snackerfish
You can use a formset here. In your case - take django-jsonfield or django-picklefield to avoid manual converting to/from data on object's saving and retrieving, and create a formset providing empty list on init.
You can manipulate it on client side using js, but do not forget to increment forms count in TOTAL_FORMS hidden input. After POSTing the form and cleaning the data you'll have formset.cleaned_data() which you could put to your PickleField without any aditional processing (and data from the field can be put as initial to formset if you'll need to edit the recipe).