I am a beginner in Django, hence this might be a simple issue. But I'm not able to get past this successfully.
This is my models.py
class Category(models.Model):
name = models.CharField(max_length=128)
abbr = models.CharField(max_length=5)
def __unicode__(self):
return self.name
class Fabric(models.Model):
name = models.CharField(max_length=128)
abbr = models.CharField(max_length=5)
def __unicode__(self):
return self.name
class Manufacturer(models.Model):
name = models.CharField(max_length=128)
location = models.CharField(max_length=128)
name_abbr = models.CharField(max_length=5, default=None)
loc_abbr = models.CharField(max_length=5, default=None)
def __unicode__(self):
return self.name
class Images(models.Model):
design_id = models.CharField(max_length=128)
file = models.ImageField(upload_to='images')
cost_price = models.FloatField()
category = models.ForeignKey(Category, on_delete=models.CASCADE)
fabric = models.ForeignKey(Fabric, on_delete=models.CASCADE)
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
selling_price = models.FloatField()
aliveness = models.IntegerField()
date_added = models.DateTimeField(default=datetime.datetime.now)
set_cat = models.IntegerField()
set_cat_no = models.IntegerField()
set_cat_name = models.CharField(max_length=50, blank=True)
I'm building an apparel management database system which contains cloth designs.
My forms.py is
class ImagesForm(forms.ModelForm):
class Meta:
model = Images
fields = ('file','cost_price','set_cat_no','set_cat_name',)
My views.py
#login_required
def uploadphoto(request):
context = RequestContext(request)
context_dict = {}
if request.method == 'POST':
form = ImagesForm(request.POST,request.FILES)
if form.is_valid():
image = form.save(commit=False)
image.save()
return render_to_response(request,'cms/upload-photo.html', {'upload_image': form})
else:
print form.errors
else:
form = ImagesForm()
context_dict = {'upload_image': form}
return render_to_response('cms/upload-photo.html',context_dict, context)
My upload-photo.html is
{% block main %}
<form id="upload_form" method="post" action="/zoomtail/upload-photo/" enctype="multipart/form-data">
{% csrf_token %}
{{ upload_image }}
</form>
{% endblock %}
The problem here is when I goto /upload-photo/ I don't see the drop-downs to the foreign keys to categories, fabric and manufacturers. I have read that it should be automatically generated but I don't see any.
And selling_price has to be calculated based on the given percentage increase from the cost_price which has to be entered in the form. How do I do this? And aliveness of an apparel has to be set by default as 1. How to do this?
set-cat field of an apparel is 1 if it belongs to a set and 2 if it belongs to a catalogue. How do I get a radio button asking whether set or catalogue and that to be captured as an integer in the database?
And design-id field of an apparel has to be a string which contains abbreviations of category, fabric, manufacturer, etc etc all the fields it belongs to. How do I do this dynamically?
I know, this is a very long question but I'm a newbie and these are literally giving me headache since days. I shall be very thankful to those who answer this.
I believe the issue with the dropdown is that you've excluded the fields from ImageForm. You have:
fields = ('file','cost_price','set_cat_no','set_cat_name',)
but should have:
fields = ('file','cost_price','set_cat_no','set_cat_name', 'category', 'fabric', 'manufacturer,)`
if that doesn't work, are there any options in your database for Categories, Fabric, and Manufacturer? If your tables are empty, the dropdown will be empty. If there are values in the database, is there HTML being generated but the label value is blank (i.e. <option>{this is blank}</option>)? In django, you can override the __str__ function to specify how the dropdown options get labeled
Override __str__ as follows:
class Category(models.Model):
name = models.CharField(max_length=128)
abbr = models.CharField(max_length=5)
def __unicode__(self):
return self.name
def __str__(self):
return self.name
You can compute the value of selling_price and any other computed value in the block if request.method == 'POST'.
Example:
def uploadphoto(request):
context = RequestContext(request)
context_dict = {}
if request.method == 'POST':
form = ImagesForm(request.POST,request.FILES)
#- Calculate value(s) here -#
if form.is_valid():
image = form.save(commit=False)
image.save()`
Please see this post here for using radio buttons
You would do this in the same place as #2 above
Related
I am making a small project to rate salesmen. I have regions and each region has its salesmen. So, if region "blahblah" is selected, form should show salesmen choices which are related to that region. I have found some answers via stackoverflow, but it still shows all salesmen, regardless of their regions.
My model is this:
class Region(models.Model):
name = models.CharField(max_length=50)
slug = models.SlugField(max_length=50, unique=True)
def __str__(self):
return self.name
class Salesman(models.Model):
region = models.ForeignKey(Region,
related_name='region',
on_delete=models.CASCADE)
name = models.CharField(max_length=40)
surname = models.CharField(max_length=40)
def __str__(self):
return self.name
class Rating(models.Model):
RATING_CHOICES = [(i, str(i)) for i in range(1,6)]
salesman = models.ForeignKey(Salesman,
related_name='salesman',
on_delete=models.CASCADE)
phone = models.CharField(max_length=15, blank=True)
rating = models.IntegerField(choices=RATING_CHOICES, blank=False)
sent_time = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.phone
I found modified __init__ method for my forms.py:
class RateAddForm(forms.ModelForm):
class Meta:
model = Rating
def __init__(self, region_id=None, **kwargs):
super(RateAddForm, self).__init__(**kwargs)
if region_id:
self.fields['salesman'].queryset = Salesman.objects.filter(region=region_id)
And also my views.py is this:
def report_add(request, region_id):
if request.method == 'POST':
print(region_id)
form = RateAddForm(request.POST, region_id=region_id)
if form.is_valid():
message = "Thanks!"
form.save()
return HttpResponse(message)
else:
print("Something went wrong!")
form = RateAddForm()
else:
form = RateAddForm(request.POST)
return render(request,
'account/report.html',
{'form': form})
It still shows me all salesmen on my database, even if i choose a region. How to solve this problem that form should show only salesmen of selected region. Thanks in advance!
Try setting the self.base_fields['salesman'].queryset instead of
self.fields['salesman'].queryset (i.e "base_fields" instead of "fields").
(That's what I do when I need to filter in Admin forms)
How can I display the list of users with the count of total number of posts made by them in a separate HTML page ?
models.py
class Post(models.Model):
author = models.ForeignKey(User.request, on_delete = models.CASCADE)
title = models.CharField(max_length=100)
text = models.TextField()
slug = models.SlugField(unique=True, blank=True, default=uuid.uuid1)
created_date = models.DateTimeField(default=timezone.now)
likes = models.ManyToManyField(User, related_name='post_likes', blank = True)
def get_like_url(self):
return reverse("posts:like-toggle", kwargs={"slug": self.slug})
def get_api_like_url(self):
return reverse("posts:like-api-toggle", kwargs={"slug": self.slug})
def get_absolute_url(self):
return reverse("post_detail",kwargs={'pk':self.pk})
def __str__(self):
return self.title
def count_posts_of(user):
return Post.objects.filter(author=user).count()
You have to learn MVC architecture(MVT in django).
As a beginner first create a sample project to understand this - https://docs.djangoproject.com/en/2.0/intro/tutorial01/
Learn how models.py are written - https://docs.djangoproject.com/en/2.0/topics/db/models/
and how to writeviews.py - https://docs.djangoproject.com/en/2.0/topics/class-based-views/
Then connect them in urls.py - https://docs.djangoproject.com/en/2.0/topics/http/urls/
This is my solution at the moment, but it could be done differently.
First, add count_posts_of method to your User model whatever it is.
For instance I myself created a user model and add this method to it as following:
models.py
class User(models.Model):
name = models.CharField(max_length=100, blank=True, null=True)
#property
def count_posts_of(self):
return self.post_set.all().count()
now in the view pass all the users as context:
views.py
def user_post(request):
context = {'users': User.objects.all()}
return render(request, 'future/user_post_view.html', context)
and finally in the template show the user and their posts' count:
user_post_view.html
{% for user in users %}
{{ user.name }} :
{{ user.count_posts_of }},
{% endfor %}
I am very new to Django as well as Python. I am trying to build a small Resource management tool. Below is what I have come up with till now.
I Extended a User Model
I have created other required models like Current address Permanent Address etc.
I have a sample form in forms.py
I have a profile.html page.
As of now when a user is logged , and when he clicks on update profile he is redirected to Profile.html page where he gets fields from ModelForm Employee (Data pulled from DB) which is just a extended userModel. (Infact user should not be able to edit any of the field in this form, this should be just a read only field as this will be set by Admin, but this Problem is later part for me, I do not know how to bring as a ReadOnly field have not researched yet on this)
What I want to do is now I want to show all the other forms also (ModelForms of Current Address, Permanent address etc on the same same page for that particular user so he can update the records) Till now I tried different methods but I couldn't get hold of any proper solution Can anyone help me on this. Below are my models, views, forms and html page. I am open for any alternative solution which is easy and secure as this I have started recently so I am ok to change whatever required to be changed. All the other models are linked to foreign Key emp_id from Employee model. Apologies for the Long question but I am stuck at this point and I unable to go ahead from this point.
Forms:
#User Profile Form to update the user profile
class UserProfileForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(UserProfileForm, self).__init__(*args, **kwargs)
# If you pass FormHelper constructor a form instance
# It builds a default layout with all its fields
self.helper = FormHelper(self)
# You can dynamically adjust your layout
helper = FormHelper()
helper.form_class = 'form-horizontal'
helper.layout = Layout(
Field('text_input', css_class='input-xlarge'),
Field('textarea', rows="3", css_class='input-xlarge'),
'radio_buttons',
Field('checkboxes', style="background: #FAFAFA; padding: 10px;"),
AppendedText('appended_text', '.00'),
PrependedText('prepended_text', '<input type="checkbox" checked="checked" value="" id="" name="">', active=True),
PrependedText('prepended_text_two', '#'),
'multicolon_select',
FormActions(
Submit('save_changes', 'Save changes', css_class="btn-primary"),
Submit('cancel', 'Cancel'),
)
)
self.helper.layout.append(Submit('save_changes', 'Update'))
class Meta:
model = Employee
exclude = ('user',)
Views:
#login_required
def user_profile(request):
if request.method == 'POST':
form = UserProfileForm(request.POST, instance=request.user.profile)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/loggedin/')
else:
user = request.user
profile = user.profile
form = UserProfileForm(instance=profile)
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('profile.html', args)
profile.html:
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<h2> Profile </h2>
{% crispy form %}
{% endblock %}
Models.
#Department Model
class Dept(models.Model):
dept_name = models.CharField(max_length=30)
def __unicode__(self):
return self.dept_name
#Extending User Model
class Employee(models.Model):
user = models.OneToOneField(User, null=True, blank = True, verbose_name="User Id")
emp_id = models.IntegerField(primary_key=True, max_length=5, verbose_name="Employee Id")
emp_first = models.CharField('First Name',max_length=20)
emp_middle = models.CharField('Middle Name', blank=True, max_length=20)
emp_last = models.CharField('Last Name',max_length=20)
emp_email = models.EmailField('Email Id')
emp_dept = models.ForeignKey(Dept, verbose_name="Department")
def __unicode__(self):
return self.emp_first
User.profile = property(lambda u: Employee.objects.get_or_create(user=u)[0])
#Current Address Model
class CurrentContact(models.Model):
emp = models.ForeignKey(Employee)
emp_add = models.TextField('Current Address')
emp_city = models.CharField('City', max_length=20, default = 'Bangalore')
emp_state = models.CharField('State', max_length=20, default= 'Karnataka')
emp_country = models.CharField('Country', max_length=20, default = 'India')
emp_mobile1 = models.IntegerField('Mobile1',max_length=12)
emp_mobile2 = models.IntegerField('Mobile2', null=True, blank=True, max_length=12)
emp_landline = models.IntegerField('Land Line',null=True, blank=True, max_length=12)
emp_PerEmail = models.EmailField('Personal Email Id', blank=True)
def __unicode__(self):
return self.emp
#Permanent Address Model
class PermanentContact(models.Model):
emp = models.ForeignKey(Employee)
emp_add = models.TextField('Permanent Address')
emp_city = models.CharField('City', max_length=20, default = 'Bangalore')
emp_state = models.CharField('State', max_length=20,default= 'Karnataka')
emp_country = models.CharField('Country', max_length=20, default = 'India')
emp_mobile1 = models.IntegerField('Mobile1',max_length=12)
emp_mobile2 = models.IntegerField('Mobile2', null=True, blank=True, max_length=12)
emp_landline = models.IntegerField('Land Line',null=True, blank=True, max_length=12)
emp_PerEmail = models.EmailField('Personal Email Id', blank=True)
def __unicode__(self):
return self.emp
#Emergency Contact Model
class Emergency(models.Model):
emp = models.ForeignKey(Employee)
emrg_name = models.CharField('Full Name', max_length=30)
emrg_add = models.TextField('Full Address')
emrg_city = models.CharField('City', max_length=20, default = 'Bangalore')
emrg_state = models.CharField('State', max_length=20,default= 'Karnataka')
emrg_country = models.CharField('Country', max_length=20, default = 'India')
emrg_mobile1 = models.IntegerField('Mobile1', max_length=12)
emrg_mobile2 = models.IntegerField('Mobile2', null=True, blank=True, max_length=12)
emrg_landline = models.IntegerField('Land Line',null=True, blank=True, max_length=12)
emrg_PerEmail = models.EmailField('Email Id', blank=True)
def __unicode__(self):
return self.emp
Have you taken a look here:
Django: Changing User Profile by forms
It seems like an almost identical question to yours.
I'm using Pinax to create a new project. For this project I needed to create a new app 'Business' which is much like Profiles but they wanted to keep everything seperate for Businesses.
I'm trying to have the admin be able to change the logo or "avatar" for the business profile. Im using the ImageModel class from Photologue to control the image upload, etc but I ran into a problem. When going through the form, the form goes through and redirects but the image doesn't actually get updated. When you go through the django admin, the image uploads fine.
If someone could take a look and see if something is missing, I've been staring at it for too long, so I need a fresh pair of eyes.
Business Models.py
class Business(models.Model):
name = models.CharField(verbose_name="Name", max_length=140)
desc = models.TextField(verbose_name="Description", null=True, blank=True)
bus_type = models.CharField(verbose_name="Business Type", choices=BUSINESS_TYPES, max_length=20)
location = models.CharField(_("location"), null=True, blank=True, max_length=200)
website = models.URLField(_("website"), null=True, blank=True, verify_exists=False)
created_by = models.ForeignKey(User, related_name="Created By")
admin = models.ManyToManyField(User, related_name="Admin User", null=True, blank=True)
followers = models.ManyToManyField(User, related_name="Followed by", null=True, blank=True)
date_added = models.DateField(verbose_name="Date Added")
class Meta:
verbose_name = "Business"
verbose_name_plural = "Businesses"
def __unicode__(self):
return self.name
class BusinessLogo(ImageModel):
business = models.ForeignKey(Business, related_name="Business Association")
My views.py
#login_required
def changeLogo(request, bus_id):
user = request.user
b = get_object_or_404(Business, pk = bus_id)
if request.method == 'POST':
form = ChangeLogoForm(request.POST, request.FILES, instance = b)
if form.is_valid():
biz_logo = form.save(commit=False)
biz_logo.save()
return HttpResponseRedirect('/')
else:
form = ChangeLogoForm()
return render_to_response('business/changelogo.html',
{'user': user, 'form':form, 'b':b}, context_instance=RequestContext(request))
Forms.py
class ChangeLogoForm(ModelForm):
class Meta:
model = BusinessLogo
def save(self, force_insert=False, force_update=False, commit=True):
f = super(ChangeLogoForm, self).save(commit=False)
if commit:
f.save()
print "form save method was called with commit TRUE"
return f
And finally my changelogo.html
...
{% block body %}
<h1>Change Logo</h1>
<form method="POST" action="" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Upload">
</form>
{% endblock %}
...
Thanks everyone, for taking a look.
Steve
The ChangeLogoForm's model is BusinessLogo, but when calling it's constructor you pass it a Business instance:
b = get_object_or_404(Business, pk = bus_id)
...
form = ChangeLogoForm(request.POST, request.FILES, instance = b)
(And you should probably use a OneToOneField field instead of ForeignKey)
I am building a form for a store that will allow clients to choose a price from a number of choices. The current Django template looks like so and works very well.
<select>
<option>{{ p.equipment_list.season_price.currency }} {{ p.equipment_list.season_price.daily }} per day.</option>
<option>{{ p.equipment_list.season_price.currency }} {{ p.equipment_list.season_price.weekly }} per week.</option>
<option>{{ p.equipment_list.season_price.currency }} {{ p.equipment_list.season_price.monthly }} per month.</option>
</select>
I have a product 'p' that is part of a group called Equipment List. This list has different pricing (season_price) depending on the time of year or through an sale offer. This allows maximum customizability and separation of tasks. Here are the models:
class SeasonPrice(models.Model):
name = models.CharField(_('Season Price'), max_length=300)
slug = models.SlugField(max_length=150, unique=True)
description = models.TextField(blank=True)
currency = models.ForeignKey(Currency)
daily = models.DecimalField(max_digits=10, decimal_places=2)
weekly = models.DecimalField(max_digits=10, decimal_places=2)
monthly = models.DecimalField(max_digits=10, decimal_places=2)
…
class EquipmentList(models.Model):
...
name = models.CharField(_('Equipment List'), max_length=100)
slug = models.SlugField(unique=True)
description = models.TextField(blank=True)
season_price = models.ForeignKey(SeasonPrice)
….
class Product(ImageModel):
...
equipment_list = models.ForeignKey(EquipmentList, related_name='Equipment')
name = models.CharField('Name', max_length=300)
slug = models.SlugField(max_length=150, unique=True)
description = models.TextField()
is_active = models.BooleanField(default=True)
quantity = models.IntegerField()
…
#models.permalink
def get_absolute_url(self):
return ('product_detail', (), {'product_slug': self.slug})
….
The form looks something like this:
class ProductAddToCartForm(forms.Form):
...
product_slug = forms.CharField(widget=forms.HiddenInput())
price = forms.ModelChoiceField(EquipmentList)
quantity = forms.IntegerField(widget=forms.TextInput(attrs={'size':'2', 'value':'1', 'class':'quantity'}),
error_messages={'invalid':'Please enter a valid quantity.'},
min_value=1)
...
And the View:
def show_product(request, product_slug, template_name="shop/product_detail.html"):
p = get_object_or_404(Product, slug=product_slug)
page_title = p.name
# need to evaluate the HTTP method
if request.method == 'POST':
postdata = request.POST.copy()
form = ProductAddToCartForm(request, postdata)
if form.is_valid():
cart.add_to_cart(request)
url = urlresolvers.reverse('show_cart')
return HttpResponseRedirect(url)
else:
form = ProductAddToCartForm(request=request, label_suffix=':')
form.fields['product_slug'].widget.attrs['value'] = product_slug
request.session.set_test_cookie()
return render_to_response("shop/product_detail.html", locals(), context_instance=RequestContext(request))
All the examples that I have seen of ModelChoiceField are one ForeignKey deep. From the above, I want to be able to chain-link 2 to 3 ForeignKeys and output a numeral string to be multiplied with the quantity the shopper wants and then place into a shopping cart.
Thanks
I don't think that ModelChoiceField is appropriate for the original <select> you show. You are choosing a currency/decimal combination, not a model instance. Probably, you want to build an ad-hoc ChoiceField.
myform.fields['price'].choices = (
('1::3.50', "EUR 3.50 per day"),
# ...
)
where 1::3.50 can be split() in clean/save to give the currency id and the amount string. Something like that.