Django, How to update the DateTimeField() of model by the view - django

As mentioned in the title, I have a model containing the DateTimeField()
models.py
class DataRow(models.Model):
last_edit_date = models.DateTimeField(default=datetime.now())
I would like to update this field every time I call the model in view. I tried to do it as follows:
views.py
data_row = get_object_or_404(DataRow, pk=row_id)
data_row.last_edit_date = datetime.now()
data_row.save()
I also checked the auto_add=True attribute and calling the .save() method of model, but it did not work either.

Answer to this question is in the comments above.

Related

How to update through model in django many to many?

class Blog():
likes = models.ManyToManyField(User, through="myapp.Like")
class Like():
user = models.ForeignKey(Like)
blog = models.ForeignKey(Blog)
liked_at = models.DateTimeField(auto_now_add=True)
some_bool_field = models.BooleanField(default=False)
Now in views:
def like_blog(request, id):
blog = Blog.objects.get(id=id)
blog.users.add(request.user)
# now how can I update some_bool_field and How can I make use of this field
In future I can use some query like blog.users.filter(some_bool_field=False) so for that case I want to update this field.
OR AM I MISSING THE USES OF THROUGH MODEL ?
If you want to update the through model objects you can do like so:
def like_blog(request, id):
blog = Blog.objects.get(id=id)
blog.users.add(request.user)
# query your through model
Like.objects.filter(user=request.user, blog=blog).update(some_bool_field=True)
Getting all blogs filtered likes with some_bool_field=True:
true_boolean_likes = Blog.objects.filter(likes__some_bool_field=True)
for through model update you can use bellow method to update
like = Blog.objects.get(id=id)
for like in Likes.objects.filter(likes__some_bool_field =False): #or true by what you want to filter
like.the_field_want_to_update.update(id=like.id)
here .update update the value by which you are filtering here with id so it will update what data passed to it.

Django - multiple models in one page

I have a model that looks like this:
models.py
class BHA_List(models.Model):
well = models.ForeignKey(WellInfo, 'CASCADE', related_name='bha_list')
bha_number = models.CharField(max_length=100)
class BHA_Drill_Bit(models.Model):
bha_number = models.ForeignKey(BHA_List, 'CASCADE', related_name='bha_drill_bit')
bit_type = models.CharField(max_length=111)
class BHA_overall(models.Model):
bha_number = models.ForeignKey(BHA_List, 'CASCADE', related_name='bha_overall')
drill_str_name = models.CharField(max_length=111)
class BHA_Motor(models.Model):
bha_number = models.ForeignKey(BHA_List, 'CASCADE', related_name='bha_drill_bit')
motor_type = models.CharField(max_length=111)
BHA_List is a parent model, and the rest are child models related by ForeignKey. The screenshot is the page I want to create
So, I want to generate a base page using one of the instances in model = BHA_List. In this page, I want to edit model instances that are related to BHA_List by ForeignKey relationship.
I currently have a view that looks like this, but its wrong:
class BHA_UpdateView(UpdateView):
model = BHA_List
pk_url_kwarg = 'pk_alt'
form_class = BHA_overall_Form
By setting model = BHA_List, I was able to get one of the instances in BHA_List, and generate url from it. Right now my views correctly return one of the instances in BHA_List: BHA 1
I attempted to edit child models by setting form_class = BHA_overall_Form. But this doesn't do anything, though it displayed form fields on the user side. After editing and clicking Submit button, the changes are not saved in DB. Someone pointed out that this is because my model in UpdateView and form does not match, as I set model = BHA_List, but form_class = BHA_overall_form.
How can I resolve this issue? Someone else also pointed out using multiple views, but I don't really know how to do it, as I'm very new to Django. Any help will be greatly appreciated. Thanks!
Just so that you know. UpdateView can be used if you want to update a single row in one table. When you set model = BHA_LIST you are saying Django. Hey, Django I want to update this model so render me a form with the fields from this table. You can do this by just setting fields attr on the model or use a form like you did which will customize which fields are shown. Now the good thing about allowing to set our own form is. Though we create a modelForm we can also add extra fields inside it. Now your BHAOverallForm should look like this to accommodate all the fields you need.
forms.py
class BHAOverallForm(forms.ModelForm):
well = models.ForeignKey(WellInfo, 'CASCADE', related_name='bha_list')
bha_number = models.CharField(max_length=100)
bit_type = models.CharField(max_length=111
drill_str_name = models.CharField(max_length=111)
motor_type = models.CharField(max_length=111)
class Meta:
model = BHAList
you can use this form inside your form like you do now. You can also add clean_field to add validations. Now coming to the update part. your views should look like this
views.py
class BHAUpdateView(UpdateView):
model = BHAList
form_class = BHAOverallForm
def form_valid(self, form):
super(BHAUpdateView, self).form_valid(form) # save BHAList to the DB
bha_list = form.instance
bha_drill_bit = bha_list.bhadrillbit_set.first() # assuming you have only one drill_bit per list, if you need more modify your question accordingly.
bha_drill_bit.bit_type = form.cleaned_data.get("bit_type)
bha_drill_bit.save()
# you can do the same for other models as well.

CreateOrUpdateView for Django Models

In my models I have a ForeignKey relationship like this:
class Question(models.Model):
question = models.TextField(null=False)
class Answer(models.Model):
question = models.ForeignKey(Question, related_name='answer')
user = models.ForeignKey(User)
class Meta:
unique_together = (("question", "user"),)
the corresponding URL to submit an answer contains the id of the question, like this:
url(r'^a/(?P<pk>\d+)/$', AnswerQuestion.as_view(), name='answer-question'),
With user coming from self.request.user, I am trying to get something like a CreateOrUpdateView, to allow some convenient navigation for the user and URL scheme.
Until now I tried this with:
class AnswerQuestion(LoginRequiredMixin, CreateView):
and add initial value, but that isn't clean because of pk. With an UpdateView I run into problems because I have to set default values for the form.
Has anybody done something like this? I'd rather avoid having a Create and Update view for the same Answer.
The UpdateView and CreateView are really not that different, the only difference is that UpdateView sets self.object to self.get_object() and CreateView sets it to None.
The easiest way would be to subclass UpdateView and override get_object():
AnswerQuestionView(LoginRequiredMixin, UpdateView):
def get_object(queryset=None):
if queryset is None:
queryset = self.get_queryset()
# easy way to get the right question from the url parameters:
question = super(AnswerQuestionView, self).get_object(Question.objects.all())
try:
obj = queryset.get(user=self.request.user, question=question)
except ObjectDoesNotExist:
obj = None
return obj
Returns the right answer if it exists, None if it does not. Of course add any attributes you need to the class, like model, form_class etc.

Order by count of a ForeignKey field?

I have a User model and a Submission model. Each Submission has a ForeignKey field called user_submitted for the User who uploaded it.
class Submission(models.Model):
uploaded_by = models.ForeignKey('User')
class User(models.Model):
name = models.CharField(max_length=250 )
My question is pretty simple: how can I get a list of the three users with the most Submissions?
I tried creating a num_submissions method on the User model:
def num_submissions(self):
num_submissions = Submission.objects.filter(uploaded_by=self).count()
return num_submissions
and then doing:
top_users = User.objects.filter(problem_user=False).order_by('num_submissions')[:3]
But this fails, as do all the other things I've tried. Can I actually do it using a smart database query? Or should I just do something more hacky in the views file?
from django.db.models import Count
top_users = User.objects.filter(problem_user=False) \
.annotate(num_submissions=Count('submission')) \
.order_by('-num_submissions')[:3]
You didn't mention problem_user in your example model code, but I've left it in assuming that it is a BooleanField on User.

How to save fields that are not part of form but required in Django

I have a model with a field that is required but not entered by the user and i have a hard time saving the model without errors. My model definition looks like this:
class Goal(db.Model):
author = db.UserProperty(required=True)
description = db.StringProperty(multiline=True, required=True)
active = db.BooleanProperty(default=True)
date = db.DateTimeProperty(auto_now_add=True)
class GoalForm(djangoforms.ModelForm):
class Meta:
model = Goal
exclude = ['author', 'active']
And i use django-forms in appengine to create and validate the form. When i try to save the result of this form however....
def post(self):
data = GoalForm(data=self.request.POST)
if data.is_valid():
goal = data.save(commit=False)
goal.author = users.get_current_user()
goal.put()
self.redirect('/')
I get "ValueError: The Goal could not be created (Property author is required)"
Now i would think that by having commit=False, then adding the property for Goal, and then saving the object would allow me to do this but obviously it's not working. Any ideas?
Note that save() will raise a ValueError if the data in the form doesn't validate
You can find what you need about the save() method here:
http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method
Edit: Instead of goal.put(), do a goal.save()
Edit2: This should solve your problem:
goal = Goal(author='Mr') #example
data = GoalForm(data=self.request.POST, instance=goal)
I realize this is an old question, but for the sake of others searching for a similar answer, I'm posting the following:
Unless there's a reason I missed for not doing so, but I believe this is what you need:
class Goal(db.Model):
author = db.UserProperty(auto_current_user_add=True)
...
...
For reference:
Types and Property Classes:class UserProperty()
Your GoalForm should inherit from django.forms.ModelForm and be defined such that it only requires some fields:
class GoalForm(django.forms.ModelForm):
class Meta:
model = Goal
fields = ('description', 'etc')
Not sure if this is totally working in AppEngine though.
You should also save the form (still not sure about AppEngine):
data = GoalForm(data=self.request.POST)
if data.is_valid():
data.author = users.get_current_user()
data.put()