I'm unable to figure out how to only call a queryset of items that belong to a specific User in the django forms.
dropoffs/models.py
class DropoffItem(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True)
dropoff = models.ForeignKey('Dropoff', null=True, blank=True)
product = models.ForeignKey(Product)
location = models.CharField(max_length=120, choices=LOCATION_CHOICES, default="Customer")
def __str__(self):
return str('%s' + " " + "(" + '%s' + ")") %(self.product.title, self.product.sku)
def sku(self):
return self.product.sku
def title(self):
return self.product.title
def dropoff_id(self):
return str(self.dropoff.id)
forms.py
class AddPickupItemForm(forms.ModelForm):
dropoffitem = forms.ModelChoiceField(queryset=DropoffItem.objects.none())
class Meta:
model = PickupItem
# fields = ["product", "quantity"]
fields = ['dropoffitem']
def __init__(self, user, *args, **kwargs):
# self.request = kwargs.pop("request")
the_user = kwargs.pop('user', None)
super(AddPickupItemForm, self).__init__(*args, **kwargs)
if the_user is not None:
self.fields["dropoffitem"].queryset = DropoffItem.objects.filter(user=the_user)
views.py
def add_item_to_pickup_order(request):
request.session.set_expiry(120000)
try:
user = request.user
the_id = request.session['pickup_id']
pickup = Pickup.objects.get(id=the_id)
except:
user = request.user
new_pickup_order = Pickup(user=user)
new_pickup_order.save()
request.session['pickup_id'] = new_pickup_order.id
the_id = new_pickup_order.id
pickup = Pickup.objects.get(id=the_id)
try:
dropoffitem = DropoffItem.objects.filter(user=user)
except DropoffItem.DoesNotExist:
pass
except:
pass
form = AddPickupItemForm(request.POST, user=request.user)
if request.method == "POST":
dropoffitem_id = int(request.POST['dropoffitem'])
pickup_item = PickupItem.objects.create(pickup=pickup, dropoffitem_id=dropoffitem_id)
pickup_item.save()
return HttpResponseRedirect('%s'%(reverse('add_item_to_pickup_order')))
context = {
"pickup": pickup,
"form": form,
}
return render(request, 'pickups/create_pickup_order.html', context)
With the modifications to init, I'm getting a TypeError of: init() got multiple values for keyword argument 'user'.
Could that be because of how I'm requesting a 'session'?
class AddPickupItemForm(ModelForm):
def __init__(self,*args,**kwargs)
the_user = kwargs.pop('user',None)
super(AddPickupItemForm, self).__init__(*args,**kwargs)
if the_user is not None:
self.fields['dropoffitem'].queryset = DropOffItem.objects.filter(user=the_user)
In other words, pass your user to the form when instantiating, if you need to.
Related
I am getting error Cannot assign "'1'": "dropdown.drp1" must be a "basedrop" instance. I am sharing my code. Kindly help. I got some solutions on stack but I did not understand how to implement that in my case. Django error. Cannot assign must be an instance
models.py
class basedrop(models.Model):
name = models.CharField(max_length=50,blank=False,null=False)
def __str__(self):
return self.name
class subdrop(models.Model):
name = models.CharField(max_length=100,blank=False,null=False)
bsdrop = models.ForeignKey(basedrop,null=False,blank=False,on_delete=models.CASCADE)
def __str__(self):
return self.name
class lastdrop(models.Model):
name = models.CharField(max_length=100,blank=False,null=False)
sbdrop = models.ForeignKey(subdrop,null=False,blank=False,on_delete=models.CASCADE)
def __str__(self):
return self.name
class dropdown(models.Model):
name = models.CharField(max_length=50)
drp1 = models.ForeignKey(basedrop,max_length=50,on_delete=models.CASCADE)
drp2 = models.ForeignKey(subdrop,max_length=50,on_delete=models.CASCADE)
drp3 = models.ForeignKey(lastdrop,max_length=50,on_delete=models.CASCADE)
def __str__(self):
return self.name
views.py
def create_drop(request):
if request.method == 'POST':
form = dropdownForm(request.POST or None)
if form.is_valid():
form = dropdown(name=request.POST.get('name'),drp1_Id=int(request.POST.get('drp1')),
drp2_Id=int(request.POST.get('drp2')),drp3_Id=int(request.POST.get('drp3')))
form.save()
return HttpResponse('<p>this is working</p>')
form = dropdownForm()
return render(request,'drop.html',{'form':form})
forms.py
class dropdownForm(forms.ModelForm):
drp1 = forms.ChoiceField(choices=((bs.get('id'),bs.get('name')) for bs in basedrop.objects.all().values('id','name')))
class Meta:
model = dropdown
fields = '__all__'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['drp2'].queryset = subdrop.objects.none()
self.fields['drp3'].queryset = lastdrop.objects.none()
if 'drp1' in self.data:
try:
country_id = int(self.data.get('drp1'))
self.fields['drp2'].queryset = subdrop.objects.filter(id=country_id).order_by('name')
except (ValueError, TypeError):
pass
elif 'drp2' in self.data:
try:
country_id = int(self.data.get('drp2'))
self.fields['drp3'].queryset = lastdrop.objects.filter(id=country_id).order_by('name')
except (ValueError, TypeError):
pass
elif self.instance.pk:
self.fields['drp2'].queryset = self.instance.drp1.city_set.order_by('name')
self.fields['drp3'].queryset = self.instance.drp2.city_set.order_by('name')
I don't know if it could cause failures but you're passing the POSTed argument 'drp1' as integer for drp1_Id, drp2_Id and drp3_Id.
You'd have it much easier if you choose a more intuitive coding style.
For example this line:
form = dropdown(name=request.POST.get('name'), drp1_Id=int(request.POST.get('drp1')), drp2_Id=int(request.POST.get('drp1')), drp3_Id=int(request.POST.get('drp1')))
If you get the objects and pass them to the dropdown you gain readability specially if there is an error:
drp1_pk = request.POST.get('drp1')
drp1 = basedrop.objects.get(pk=drp1_pk)
drp2 = subdrop.objects.get(pk=drp1_pk)
drp3 = lastdrop.objects.get(pk=drp1_pk)
form = dropdown(name=request.POST.get('name'), drp1=drp1, drp2=drp2, drp3=drp3)
But again:
It looks strange to pass the same primary key to three different models.
I am making a retweet function and it works quite smooth but I am not able to retweet my own tweets , I am able to retweet other users tweets but not mine
. It shows that matching query doesn't exist.
Here is the tweets models
class TweetManager(models.Manager):
def retweet(self,user,parent_obj):
if parent_obj.parent:
obj_parent = parent_obj.parent
else:
obj_parent = parent_obj
qs = self.get_queryset().filter(user = user, parent = obj_parent)
if qs.exists():
return None
obj = self.model(
user = user,
parent = obj_parent,
content = parent_obj.content
)
obj.save()
return obj
class Tweet(models.Model):
parent = models.ForeignKey("self",blank = True,null = True)
user = models.ForeignKey(settings.AUTH_USER_MODEL)
content = models.CharField(max_length = 130)
time = models.DateTimeField(auto_now_add = True)
objects = TweetManager()
def __str__(self):
return self.content
class Meta:
ordering = ['content']
Here's the views.py
class Retweet(View):
def get(self, request, pk, *args, **kwargs):
tweet = get_object_or_404(Tweet, pk=pk)
if request.user.is_authenticated:
new_tweet = Tweet.objects.retweet(request.user, tweet)
return HttpResponseRedirect("/")
return HttpResponseRedirect(tweet.get_absolute_url())
I have one model Measurement, two forms MeassurementSystolicPressureForm and MeassurementDiastolicPressureForm. I want to make a view that allows user to add both of them to the database. Each has fields: username, measurement_date, value, measurement_type. When I fill forms on my webpage two records are added to the db, each has a good username and measurement_type, but measurement_date and value are the same for both records. Can you help me spotting what I'm doing wrong?
Here is my code:
models.py
class Measurement(models.Model):
value = models.IntegerField()
measurement_type = models.CharField(max_length=6, default='measurement', blank=True)
username = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
measurement_date = models.DateTimeField(default=datetime.now, editable=True)
forms.py
class MeassurementSystolicPressureForm(ModelForm):
class Meta:
model = Measurement
fields = ['value', 'measurement_date']
class MeassurementDiastolicPressureForm(ModelForm):
class Meta:
model = Measurement
fields = ['value', 'measurement_date']
views.py
def new_measurement(request):
if request.method == 'POST':
form_SP = MeassurementSystolicPressureForm(request.POST or None)
form_DP = MeassurementDiastolicPressureForm(request.POST or None)
if form_CS.is_valid() or form_CR.is_valid():
temp_S = form_SP.save(commit=False)
temp_S.username = request.user
temp_S.measurement_type = 'syspres'
temp_S.save()
temp_D = form_DP.save(commit=False)
temp_D.username = request.user
temp_D.measurement_type = 'diapres'
temp_D.save()
return redirect('/')
else:
form_SP = MeassurementSystolicPressureForm()
form_DP = MeassurementDiastolicPressureForm()
args = {'form_SP': form_SP, 'form_DP': form_DP}
return render(request, 'measurements.html', args)
If for example I submit data for:
Systolic Pressure:
value: 120
date: 2019-01-15 16:15:32
Diastolic Pressure:
value: 80
date: 2019-01-15 15:00:00`
In my database I have two records:
username: Julka, measurement_type:
syspres, value: 80, date: 2019-01-15 15:00:00
username: Julka, measurement_type: diapres, value: 80, date: 2019-01-15 15:00:00
I have no idea what to do.
In an HttpRequest object, the GET and POST attributes are instances of django.http.QueryDict. This type alone cannot determine which form was submitted. Your forms have the same fields, so then one form is valid, other form valid too. That's why you have measurement_date and value are the same for both records. To solve this problem, you can add additional hidden fields to your forms and look at them from which form was sent. Some like this:
class MeassurementSystolicPressureForm(ModelForm):
flag_Systolic = forms.IntegerField()
class Meta:
model = Measurement
fields = ['value', 'measurement_date']
def __init__(self, *args, **kwargs):
super(MeassurementSystolicPressureForm, self).__init__(*args, **kwargs)
self.fields['flag_Systolic'].widget = forms.HiddenInput()
class MeassurementDiastolicPressureForm(ModelForm):
flag_Diastolic = forms.IntegerField()
class Meta:
model = Measurement
fields = ['value', 'measurement_date']
def __init__(self, *args, **kwargs):
super(MeassurementDiastolicPressureForm, self).__init__(*args, **kwargs)
self.fields['flag_Diastolic'].widget = forms.HiddenInput()
and in your views:
def new_measurement(request):
if request.method == 'POST':
if 'flag_Systolic' in request.POST:
form_SP = MeassurementSystolicPressureForm(request.POST)
if form_SP.is_valid():
temp_S = form_SP.save(commit=False)
temp_S.username = request.user
temp_S.measurement_type = 'syspres'
temp_S.save()
return redirect('/')
elif 'flag_Diastolic' in request.POST:
form_DP = MeassurementDiastolicPressureForm(request.POST)
if form_DP.is_valid():
temp_D = form_DP.save(commit=False)
temp_D.username = request.user
temp_D.measurement_type = 'diapres'
temp_D.save()
return redirect('/')
else:
form_SP = MeassurementSystolicPressureForm()
form_DP = MeassurementDiastolicPressureForm()
args = {'form_SP': form_SP, 'form_DP': form_DP}
return render(request, 'measurements.html', args)
I know maybe it is too late but it might be helpful for other people facing the same problem.
One easier solution would be creating the object in the View and passing it to both forms:
from .models import Measurement
def new_measurement(request):
user=request.user #the authenticated user
if request.method == 'POST':
measurement=Measurement(username=user)
form_SP = MeassurementSystolicPressureForm(request.POST or None, instance=measurement)
form_DP = MeassurementDiastolicPressureForm(request.POST or None, instance=measurement)
if form_CS.is_valid() or form_CR.is_valid():
form_CS.save()
form_CR.save()
return redirect('/')
else:
form_SP = MeassurementSystolicPressureForm()
form_DP = MeassurementDiastolicPressureForm()
args = {'form_SP': form_SP, 'form_DP': form_DP}
return render(request, 'measurements.html', args)
I am trying to create an edit form to edit current objects using Django. I am having trouble trying to get the current id of the object in order to set the initial value to the current values of the object.
I want to create an edit form that will already show the current data before the user edits a field. How do I go about doing this?
Thanks.
my forms.py:
class AddfooditemForm(forms.Form):
quantity = forms.CharField(label="Quantity")
price_per_pound = forms.CharField(label="price_per_pound")
expiration_date = forms.CharField(label="expiration_date")
price_per_item = forms.CharField(label="price_per_item")
class AddNonFooditemForm(forms.Form):
quantity = forms.CharField(label="Quantity")
price_per_item = forms.CharField(label="price_per_item")
class EditfooditemForm(ModelForm):
quantity = forms.CharField(label="Quantity")
price_per_pound = forms.CharField(label="price_per_pound")
expiration_date = forms.CharField(label="expiration_date")
price_per_item = forms.CharField(label="price_per_item")
def __init__(self, *args, **kwargs):
super(EditfooditemForm, self).__init__(*args, **kwargs)
class Meta:
model = tasks
fields = ['quantity', 'price_per_item', 'expiration_date', 'price_per_pound']
class Edit_non_food_itemForm(ModelForm):
quantity = forms.CharField(label="Quantity")
price_per_item = forms.CharField(label="price_per_item")
def __init__(self, *args, **kwargs):
super(Edit_non_food_itemForm, self).__init__(*args, **kwargs)
class Meta:
model = tasks
fields = ['quantity', 'price_per_item']
my views.py:
#csrf_exempt
def add_item(request):
if request.method == 'POST' and 'add_food_form' in request.POST:
add_food_form = AddfooditemForm(request.POST)
if add_food_form.is_valid():
# Cleaned_data
input_type = 'food'
quantity = add_food_form.cleaned_data['quantity']
price_per_pound = add_food_form.cleaned_data['price_per_pound']
expiration_date = add_food_form.cleaned_data['expiration_date']
price_per_item = add_food_form.cleaned_data['price_per_item']
foodDict = {'price_per_item': price_per_item,
'quantity': quantity,
'price_per_pound': price_per_pound,
'expiration_date': expiration_date}
foodData = pickle.dumps(foodDict)
item = items(input_type=input_type, foodData=foodData)
item.save()
return HttpResponseRedirect(reverse('backup_app.views.items_listing'))
if request.method == 'POST' and 'add_non_food_form' in request.POST:
add_non_food_form = AddNonFooditemForm(request.POST)
if add_non_food_form.is_valid():
# Cleaned_data
input_type = 'non_food'
quantity = add_non_food_form.cleaned_data['quantity']
price_per_item = add_non_food_form.cleaned_data['price_per_item']
non_foodDict = {'quantity': quantity,
'price_per_item': price_per_item}
non_foodData = pickle.dumps(non_foodDict)
item = items(input_type=input_type, non_foodData=non_foodData)
item.save()
return HttpResponseRedirect(reverse('backup_app.views.items_listing'))
else:
'add_food_form': AddfooditemForm()
'add_non_food_form': AddNonFooditemForm()
return render(request, 'backup_app/items_listing.html', {'add_food_form': add_food_form,'add_non_food_form': add_non_food_form})
#csrf_exempt
def edit_item(request, item_id):
item = items.objects.get(id=item_id)
if request.method == 'POST' and 'edit_food_form' in request.POST:
edit_food_form = EditfooditemForm(request.POST, instance=item)
if edit_food_form.is_valid():
print "valid"
# Cleaned_data
item.input_type = 'food'
quantity = edit_food_form.cleaned_data['quantity']
price_per_pound = edit_food_form.cleaned_data['price_per_pound']
expiration_date = edit_food_form.cleaned_data['expiration_date']
price_per_item = edit_food_form.cleaned_data['price_per_item']
foodDict = {'price_per_item': price_per_item,
'quantity': quantity,
'price_per_pound': price_per_pound,
'expiration_date': expiration_date}
item.foodData = pickle.dumps(foodDict)
item.save()
return HttpResponseRedirect(reverse('backup_app.views.items_listing'))
if request.method == 'POST' and 'edit_non_food_form' in request.POST:
edit_non_food_form = Edit_non_food_itemForm(request.POST, instance=item)
if edit_non_food_form.is_valid():
# Cleaned_data
item.input_type = 'non_food'
quantity = edit_non_food_form.cleaned_data['quantity']
price_per_item = edit_non_food_form.cleaned_data['price_per_item']
non_foodDict = {'quantity': quantity,
'price_per_item': price_per_item}
item.non_foodData = pickle.dumps(non_foodDict)
item.save()
return HttpResponseRedirect(reverse('backup_app.views.items_listing'))
else:
context = {
'edit_food_form': EditfooditemForm(instance=item),
'edit_non_food_form': Edit_non_food_itemForm(instance=item)
}
return render(request, 'backup_app/items_listing.html', context)
Try something like this:
forms.py:
class ChangeForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ['field1', 'field2']
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
super(ChangeForm, self).__init__(*args, **kwargs)
views.py:
# To render multiple forms, repeat the process
def account_settings(request):
change_form = ChangeForm(request.POST or None,
instance=request.user, user=request.user)
change_form_2 = ChangeForm2(request.POST or None)
if request.method == 'POST':
if change_form.is_valid():
change_form.save()
if change_form_2.is_valid():
change_form_2.save()
context = {
'change_form': change_form,
'change_form_2': change_form_2
}
return render(request, 'change_form.html', context)
That should give you the current data.
Note: Change the attributes to your needs. If you post your code, I can help you with that. However, I don't know what you're working with, but the above should be a good template to follow.
EDIT:
views.py:
#csrf_exempt
def add_item(request):
add_food_form = AddfooditemForm(request.POST or None)
add_non_food_form = AddNonFooditemForm(request.POST or None)
if request.method == 'POST':
if add_food_form.is_valid():
input_type = 'food'
quantity = add_food_form.cleaned_data['quantity']
price_per_pound = add_food_form.cleaned_data['price_per_pound']
expiration_date = add_food_form.cleaned_data['expiration_date']
price_per_item = add_food_form.cleaned_data['price_per_item']
foodDict = {'price_per_item': price_per_item,
'quantity': quantity,
'price_per_pound': price_per_pound,
'expiration_date': expiration_date}
foodData = pickle.dumps(foodDict)
item = items(input_type=input_type, foodData=foodData)
if add_non_food_form.is_valid():
input_type = 'non_food'
quantity = add_non_food_form.cleaned_data['quantity']
price_per_item = add_non_food_form.cleaned_data['price_per_item']
non_foodDict = {'quantity': quantity,
'price_per_item': price_per_item}
non_foodData = pickle.dumps(non_foodDict)
item = items(input_type=input_type, non_foodData=non_foodData)
item.save()
# This needs to be a url name
return HttpResponseRedirect(reverse('url_name_here'))
context = {
'add_food_form': add_food_form,
'add_non_food_form': add_non_food_form
}
# Make this its own template
return render(request, 'backup_app/items_add.html', context)
#csrf_exempt
def edit_item(request, item_id):
item = items.objects.get(id=item_id)
edit_food_form = EditfooditemForm(request.POST or None,
instance=item)
edit_non_food_form = Edit_non_food_itemForm(request.POST or None,
instance=item)
if request.method == 'POST':
if edit_food_form.is_valid():
item.input_type = 'food'
quantity = edit_food_form.cleaned_data['quantity']
price_per_pound = edit_food_form.cleaned_data['price_per_pound']
expiration_date = edit_food_form.cleaned_data['expiration_date']
price_per_item = edit_food_form.cleaned_data['price_per_item']
foodDict = {'price_per_item': price_per_item,
'quantity': quantity,
'price_per_pound': price_per_pound,
'expiration_date': expiration_date}
item.foodData = pickle.dumps(foodDict)
if edit_non_food_form.is_valid():
item.input_type = 'non_food'
quantity = edit_non_food_form.cleaned_data['quantity']
price_per_item = edit_non_food_form.cleaned_data['price_per_item']
non_foodDict = {'quantity': quantity,
'price_per_item': price_per_item}
item.non_foodData = pickle.dumps(non_foodDict)
item.save()
# This needs to be a url name
return HttpResponseRedirect(reverse('url_name_here'))
else:
context = {
'edit_food_form': EditfooditemForm(instance=item),
'edit_non_food_form': Edit_non_food_itemForm(instance=item)
}
# Make this its own template
return render(request, 'backup_app/items_edit.html', context)
def items_listing(request):
# Any data you want to post about the listed items
return render(request, 'backup_app/items_listing.html', {})
Here is models.py:
class User(TimeStampedModel):
id = models.AutoField(primary_key=True)
class Shoe(models.Model):
size = models.IntegerField(help_text="The shoe\'s size", choices=sizeChoices)
user = models.ForeignKey('User', related_name='shoes')
brand = models.ForeignKey('Brand', related_name='shoes')
class Brand(models.Model):
name = models.CharField(max_length=64, choices = brandChoices)
class ShoeForm(ModelForm):
def __init__(self, *args, **kwargs):
super(ShoeForm, self).__init__(*args, **kwargs)
self.fields['brand'].required = True
self.fields['size'].required = True
class Meta:
model = Shoe
fields = ['brand', 'size']
exclude = ['user']
views.py:
def index(request):
ShoeFormSet = modelformset_factory(Shoe, form=ShoeForm, extra=3)
NewShoeFormSet = modelformset_factory(Shoe, form=NewShoeForm)
if request.method == 'POST':
shoe_formset = ShoeFormSet(request.POST, request.FILES, prefix='shoes')
new_shoe_formset = NewShoeFormSet(request.POST, request.FILES, prefix='new_shoes')
if shoe_formset.is_valid() and new_shoe_formset.is_valid():
#do something with the cleaned data
else:
shoe_formset = ShoeFormSet(prefix='shoes')
new_shoe_formset = NewShoeFormSet(prefix='new_shoes')
return render(request, 'shoes/input_shoes.html', {
'shoe_formset': shoe_formset,
'new_shoe_formset': new_shoe_formset,
})
But I get this error: DatabaseError: no such column: shoes_shoe.user_id, which occurs on the line shoe_formset = ShoeFormSet(prefix='shoes') when the form renders. What's going wrong?