Need Suggestion Regarding Models


#1

I have a Model named “profile” with couple of data like Name, Description etc. What I want to add is a collection of data (per user i.e per Profile) that will be stored in the form of dictionary or tuples.
Example: To store Weight of a person coupled with the date on which he made the entry.
Please help me!
Regards


#2

Hey there! Sounds like you’d want multiple models. For example:

Profile:
— name
— description

Weight:
— weight
— date_added
— profile (foreignkey model)

Then, you can add Weight entries per profile, and then if you need to have all weights, you can query for all Weights tied to that profile.

Have you taken a look at the Intermediate Concepts (http://hellowebapp.com/intermediate-concepts) book yet? I have an entire chapter on multiple models, it would help you a lot. :)


#3

Thank you! Just realized your second book had all the details like adding social networks and stuff. Hadn’t started with it yet.
Thanks for writing such a cool book, else finding about many-to-one relationship in Django seemed confusing.


#4

It’s confusing to start but I promise it gets better. :)

Regarding the many-to-one stuff, think of databases like giant spreadsheets. You should put all information about a profile in one spreadsheet and the weights they add in a second spreadsheet. Django makes it pretty easy to form a connection between those two sheets (via ForeignKey, which is a many-to-one relationship).

If you set up related_name on your ForeignKey like this:

class Profile(models.Model):
    (profile model fields)

class Weight(models.Model):
    profile = models.ForeignKey(Profile, related_name="weights")
    (rest of the fields)

You could do queries to get all weights for a profile like this:

profile = Profile.objects.get(id=1)
profile_weights = profile.weights.all()

And then you can do fun things like loop over the weights and create graphs and whatnot.

Let me know if any of that doesn’t make sense!


#5

profile = models.ForeignKey(Profile, related_name=“weights”)
Here each object of Class Profile is tied to a particular object of Class Weight related by a key called “weights”.
Did I get it right?

profile_weights = profile.weights.all()
What is “profile.weights”? Shouldn’t I be calling objects of class Weight to extract the values? Can just using the key display the data?


#6

profile.weightsprofile is the object I grabbed in the first line, and weights is the related_name I added to the Weight model, the ForeignKey that links the weight and the profile.

It’s a shortcut so you can get every object that’s tied to another object — in my example, every weight that was added in the Weight model that is linked to a specific profile.


#7

Got it thanks.
BTW I followed your second book and successfully added weight, but you’ve shown how to add weight via admin panel. Getting confused as how to add it in the form. Will I have to create a new form apart from the existing form named “ThingForm” or can I add weight as a field in “ThingForm”.


#8

Being that it’s a separate model, it would be easiest to create a separate form. You can also make a custom form (which is also covered in Intermediate Concepts) that saves to the models instead, but it would be harder because you’re not doing the ModelForm shortcut. But still doable! :)


#9

Got it. Thanks a lot. :)


#10

Hi, I’m trying to implement this method in a separate form. Everything is working, apart from the request to draw data from the model.

The problem seems to be with this line, which is missing logic to grab data from the model:

form = form_class(data=request.POST, instance=company).

This the full section from views.py.

def edit_profile(request, slug):
# grab the object…
profile = Profile.objects.get(slug=slug)

weights = Weights.objects.get()

# set the form we're using...
form_class = WeightForm

 # if we're coming to this view from a submitted form,
# do this
if request.method == 'POST':
    # grab the data from the submitted form and
    # apply to the form
    form = form_class(data=request.POST, files=request.FILES, instance=weights)

    if form.is_valid():
        # save the new data

        Weight.objects.create(
           weight=form.cleaned_data['weight'], 
           date_added=form.cleaned_data['date_added'], 
           profile=profile,

            )
        # our new message!
        messages.success(request, 'Profile details updated.')

        return redirect('profile_detail', slug=profile.slug)
# otherwise just create the form
else:
    form = form_class(instance=weights)


# and render the template
return render(request, 'companys/edit_company.html', {
    'profile': profile,
    'form': form,
})

Thanks so much for your help.

Apologies - I worked it out - the instance was wrong, so need to reply.


#11

Was that “no need”? :D