Calling django query sets when user needs them - django

I have been going back and forward with ideas doing this and none of them has worked so I'm gonna ask for ideas. I have model called "List" that users can create for example "Sleep" Then they have input where they select one of their lists and can add value for example 8. Good sleep! After that user sees a graph based on the data that he/(she has entered. All that is already working but I cannot seem to find a way to get data organized.
I'm trying to do it so list "sleep" calls all it's values to the graph and then other list lets say "money" shows all its money values. I am using chart.js to draw the graphs and I dont care if they are all at the same time on the screen or if one by one but for somereason I cannot call these querysets properly. Only way it works is if I use .all() and that wont work since I have multiple users.
Models:
class List(models.Model):
name = models.CharField(max_length=100, default="")
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='lists')
def __str__(self):
return self.name
class Meta:
unique_together = ['name', 'user']
class DataItem(models.Model):
data = models.IntegerField(default=0)
list = models.ForeignKey(List, on_delete=models.CASCADE, related_name='data_items')r code here
Views
#login_required
def app(request):
form = list_form
form2 = data_form
user = request.user.pk
user_lists = List.objects.filter(user=user)
context = {'user_lists': user_lists, 'form': form, 'form2': form2}
return render(request, 'MyApp/app.html', context)
#require_POST
def addItem(request):
form = list_form(request.POST)
if form.is_valid():
user = request.user
new_list = List(name=request.POST['text'], user=user)
new_list.save()
return redirect('/app/')
#require_POST
def addData(request):
form = data_form(request.POST)
if form.is_valid():
new_data = DataItem(data=request.POST['data'], list=List.objects.get(id=request.POST['selection']))
new_data.save()
return redirect('/app/')
"addItem" adds an list (money and sleep)
"addData" adds an value to selected list
I have no glue where to start making what I descibed.. Should I filter the data sets in main view? make own view for it and call them with buttons?
Please be specific if you have some idea how to make that kind of function since i'm pretty new to django. Thanks :)

I take it you want to get all lists that a User has created, and then create graphs for them. First of all, I recommend adding a DateTimeField() to the DataItem model. For example: created = models.DateTimeField(auto_now_add=True).
Then, in a view, you can get all of the data for a users list like this:
#login_required
def app(request):
form = list_form
form2 = data_form
user = request.user.pk
user_lists = List.objects.filter(user=user)
list_data = {}
for list in user_lists:
list_data[list.name] = DataItem.objects.filter(list=list)
context = {'user_lists': user_lists, 'form': form, 'form2': form2, 'list_data': list_data}
return render(request, 'MyApp/app.html', context)
This will save all of the data you need in list data. If you took my advice at the beginning of the response, you could also sort it by created to get chronological. In the template, you can loop through this list. The key is the name of the list, and the value will be a queryset of the data entries.

Related

Filtering a model on a foreign key

Alright, I am pulling my hair out (and I don't have much) I have created a FormView that uses 2 models. One model simply displays some information from a table (not editable) the other Model is a form that a user selects two items from a drop down box. I need to filter the first Dropdown box. Below is the code I am using that is not working:
views.py
def assign_load(request):
form = DispatchForm(request.POST or None)
loads = Load.objects.all().filter(active=True, dispatched=False,
picked_up=False, delivered=False,
billed=False,
paid=False).order_by('start_pickup_date')
context_dict = {'dispatch' : form, 'load' : loads}
if form.is_valid():
save_it = form.save()
save_it.save()
new_dispatch = Dispatch.objects.get(id=save_it.id)
fix_load = Load.objects.get(id=new_dispatch.load_number_id)
fix_load.dispatched = True
fix_load.save()
return HttpResponseRedirect('/dispatch/dispatch/')
return render(request, 'dispatch/dispatch_form.html', context_dict)
forms.py
class DispatchForm(ModelForm):
class Meta:
model = Dispatch
fields = ['load_number', 'truck', 'start_mileage', 'end_mileage',
'pickup_date',
'pickup_time', 'delivery_date', 'delivery_time', 'driver_pay',
'fuel_cost', 'miles',
'status']
def get_queryset(self):
return self.model.objects.filter(load_number__dispatched=False)
I am trying to filter the model in forms.py I have tried using def get(), def get_queryset() and def get_context_data, none of them are returning a filtered queryset...I know I am missing something simple but I am running out of ideas any help would be great...if you need more information let me know that as well.
Thanks for all your help!

Django initial value for MultiChoice Field ignored for ModelForm

this is my first post here and I am very new to Django but I just can't seem to find a solution for this problem... I've searched stackoverflow and google but nothing seems to work for me...
I have a wine-app and want to be able to add and remove wines from the user's stock. In the list of wines the user can choose a wine to add and the ID of this wine is passed in the POST data. Since the data is getting lost after the first time the view is rendered I saved the ID in a cookie, which is working, but the problem is when I work with ModelForm de user has to select the foreign key for the user and for the wine, which is bad, so I tried to make it hidden and set the Fk_user and Fk_wine after the user choose the number of bottles to be added but before validation. Here's the problem after google everyone suggested I should use the "initial" and pass that to the form, but this is clearly not working because if I make the fields visible in the form I can see that it is not preselected...
viewy.py:
def addStockView(request):
wineId = request.POST.get('addStock')
if 'addStock' in request.POST:
wine = get_object_or_404(Wine, idwine=int(wineId))
userId = request.user.id
user = get_object_or_404(AuthUser, id=userId)
if request.method == 'POST':
#wineIdNew = request.COOKIES.get('wineIdToAdd')
#wineNew = get_object_or_404(Wine, idwine=wineIdNew)
form = StockForm(request.POST, initial={'fk_wine': wineNew.idwine, 'fk_auth_user': user.id})
if form.is_valid():
form.save()
return redirect('home')
else:
form = StockForm(initial={'fk_wine': wine.id,
'fk_auth_user': user.id})
response = render(request, 'addToStock.html', {'form': form})
response.set_cookie('wineIdToAdd', wineId)
return response
forms.py:
class StockForm(forms.ModelForm):
#fk_wine = ModelChoiceField(queryset=Wine.objects.all(),
# widget=HiddenInput())
#fk_auth_user = ModelChoiceField(queryset=AuthUser.objects.all(),
# widget=HiddenInput())
class Meta:
model = UserWineStock
fields = ['fk_auth_user', 'fk_wine', 'number']
can anyone help me with this..?
Yes, initial data is ignored when a form is bound to submitted data.
Instead of using initial here, you should exclude those two fields from the form and set them on the created object:
form = StockForm(request.POST)
if form.is_valid():
item = form.save(commit=False)
item.fk_wine = wine
item.fk_auth_user = request.user
item.save()
return redirect('home')
(Also, please don't call your fields things like fk_auth_user. Just call it user.)

django form use excluded field

with django 1.5.1 I try to use the django form for one of my models.
I dont want to add the "user" field (Foreignkey) somewhere in the code instead of letting the user deceide whoes new character it is.
My Code:
Model:
class Character(models.Model):
user = models.ForeignKey(User)
creation = models.DateTimeField(auto_now_add=True, verbose_name='Creation Date')
name = models.CharField(max_length=32)
portrait = models.ForeignKey(Portrait)
faction = models.ForeignKey(Faction)
origin = models.ForeignKey(Origin)
The form:
class CreateCharacterForm(forms.ModelForm):
class Meta:
model = Character
fields = ['name', 'portrait', 'faction', 'origin']
The view:
def create_character(request, user_id):
user = User.objects.get(id=user_id)
if request.POST:
new_char_form = CreateCharacterForm(request.POST)
if new_char_form.is_valid():
new_char_form.save()
return HttpResponseRedirect('%s/characters/' % user_id)
else:
return render_to_response('create.html',
{'user': user, 'create_char':new_char_form},
context_instance=RequestContext(request))
else:
create_char = CreateCharacterForm
return render_to_response('create.html',
{'user': user, 'create_char': create_char},
context_instance=RequestContext(request))
I have tried to use a instance to incluse the userid already. i've tried to save the userid to the form before saving it, or changing the save() from my form.
I keep getting the error that character.user cant be null
I have to tell that im pretty new to django and im sure one way or another it should be possible
Can someone please help me out?
Its explained well in document model form selecting fields to use
You have to do something like this in your view
...
if request.POST:
new_char_form = CreateCharacterForm(request.POST)
if new_char_form.is_valid():
#save form with commit=False
new_char_obj = new_char_form.save(commit=False)
#set user and save
new_char_obj.user = user
new_char_obj.save()
return HttpResponseRedirect('%s/characters/' % user_id)
else:
...

how to shortlist objects in ModelForm foreign key field based upon in put

i need to shortlist Players from a specific team when i am entering a shortlisted players for a particuar match. my form field gives me a list of all players. I followed this to the letter
http://www.wkoorts.com/wkblog/2009/08/10/pre-populate-django-modelform-with-specific-queryset/
but it gives me attribute error. Here is my code forms.py
class ShortlistForm(ModelForm):
class Meta:
model = PlayerShortlist
fields = (
'player',
)
and my view.py
def shortlist(request, team_id, fixture_id):
template = get_template('cricket/shortlist.html')
loggedinuser = request.user
userteam = Team.objects.get(owner=loggedinuser)
form = ShortlistForm
#get the players only belonging to this team_id
form.fields['player'].queryset = Player.objects.filter(team=userteam)
currentteam = Team.objects.get(id=team_id)
page_vars = Context({
'form': form,
'loggedinuser': loggedinuser,
'team': userteam
})
output = template.render(page_vars)
return HttpResponse(output)
if i remove the line
form.fields['player'].queryset = Player.objects.filter(team=userteam)
it gives me this error.
AttributeError at /team/1/fixture/1/shortlist/
type object 'ShortlistForm' has no attribute 'fields'
what i am i doing wrong?
//mouse
and while we are at it, if i can list all the players with accompnying check boxes, to be put in the database, rather boss have a dropdown .. what should i choose from the formset?
//mouse
again, solved it myself.
need to initiate form first.
form = ShortlistForm
should be
form = ShortlistForm()
//mouse
Quite a bit here:
Why are you assigning request.user to loggedinuser? It's exactly the same amount of keystrokes, so you aren't saving yourself anything and only abstracting logic and adding points of failure to your code.
When assigning the form you're assigning the class, not an instance of that class. You need instead:
form = ShortlistForm()
When defining currentteam you need to catch the possibility of an incorrect team_id being passed in. The easiest way is with get_object_or_404:
currentteam = get_object_or_404(Team, id=team_id)
Unless Team.owner is a OneToOneField, you're going to run into issues with Team.owner.get(owner=loggedinuser). It's also confusing as to why you're fetching two different teams here. If you just want to filter Players to those that belong to teams that belong to the current user, the following is far more simplistic and safer:
Player.objects.filter(team__owner=request.user)
However, why you're doing this makes no sense. The comment you have says it should be filtered for the current team_id, and that makes sense based on the URL containing a team_id parameter. I'm assuming you're simply wanting to filter by the current team but also want to make sure that that team is owned by the logged in user (user has rights to it). If that's the case, the following is what you actually need:
team = get_object_or_404(Team, id=team_id, owner=request.user)
...
Player.objects.filter(team=team)
The whole bit with fetching your template, rendering it, and returning the response all manually, is unnecessary and amounts to code bloat. Just do:
# Django 1.3+
return render(request, 'cricket/shortlist.html', page_vars)
OR
# Django <1.3
return render_to_response('cricket/shortlist.html', page_vars, RequestContext(request))
Make page_vars a regular old dictionary, instead of an instance of Context, in that scenario. This also has the benefit of bring request into your template context, so you can use request.user there as well, instead of having to pass in loggedinuser.
So, with that, here's your new view:
def shortlist(request, team_id, fixture_id):
team = get_object_or_404(Team, id=team_id)
if request.method == 'POST':
form = ShortlistForm(request.POST)
#get the players only belonging to this team_id
form.fields['player'].queryset = Player.objects.filter(team=team)
if form.is_valid():
return HttpResponseRedirect('/path/to/next/view/')
else:
form = ShortListForm()
#get the players only belonging to this team_id
form.fields['player'].queryset = Player.objects.filter(team=team)
return render(request, 'cricket/shortlist.html', {
'form': form,
'team': team,
})

Saving form data rewrites the same row

i can't figure out how to save my form data creating a new row, when saving it just rewrites the data using the same 'id' and trhows me an error when there are multiple rows, this is my code:
models.py:
class Submitter(models.Model):
submitter=models.ForeignKey(User)
def __unicode__(self):
return self.submitter.username
class Store(models.Model):
creator=models.ForeignKey(Submitter)
name = models.CharField(_('name'),blank=True,max_length=30)
st = models.CharField(_('Street'),blank=True,max_length=30)
sub_date = models.DateField(_('Visit Date'),)
def __str__(self):
return u'%s-%s-%s'%(self.creator,self.name,self.sub_date)
views.py:
def StoreSave(request):
if request.method == 'POST':
form = StoreForm(request.POST)
if form.is_valid():
submitter, dummy= Creator.objects.get_or_create(creator=request.user)
store, created = Store.objects.get_or_create(
submitter=submitter
)
store.name = form.cleaned_data['name']
store.st = form.cleaned_data['st']
store.visit_date = form.cleaned_data['visit_date']
store.save()
return HttpResponseRedirect('/user/%s/' % request.user.username)
else:
form = StoreForm()
variables = RequestContext(request, {
'form': form
})
return render_to_response('store/create_store.html', variables)
If you want to create a new row, create it. :-) Like
store = Store(submitter=submitter,
name=form.cleaned_data['name'],
st=form.cleaned_data['st'],
store.visit_date=form.cleaned_data['visit_date'])
store.save()
Now you use get_or_create method which tries to find a row with given parameters, so that's why you updating it. And this method throws an error when there are multiple rows, yes, it's its normal behavior.
By the way it's better to place this saving code in form's method (save for example).
P. S. Just noticed you don't have visit_date field in your model, I think you meant sub_date.
Instead of using get_or_create you can simply use create
Store.objects.create(
submitter=submitter,
name=form.cleaned_data['name'],
st=form.cleaned_data['st'],
visit_date=form.cleaned_data['visit_date']
)
More information about the differences can be found Django Model() vs Model.objects.create()