Auto populate DateTimeField not working in django forms - django

I am getting below error when I use auto_now_add in my Model Form.
TypeError: __init__() got an unexpected keyword argument 'auto_now_add'
Here is my model field
modified = models.DateTimeField(blank = True)
Declaration in form. I have seen in one of the posts DateTimeField Not Working
to add initial = datetime.datetime.now for auto populating
import datetime
modified = forms.DateTimeField(initial = datetime.datetime.now) - When I use this no error is coming but datetime was not auto populating.
I have used the same in self.fields['modified'] - Still no use
Any of the above statements were not working. Some one help me on this.
I am pasting all my model class and Model Form here
Model Class
class Users(models.Model):
name = models.CharField(max_length = 100)
role = models.ForeignKey(RolesConfig, db_column = 'role')
level = models.ForeignKey(LevelConfig, db_column = 'level')
team_name = models.ForeignKey(TeamNamesConfig, db_column = 'team_name')
location = models.ForeignKey(LocationConfig, db_column = 'location')
modified = models.DateTimeField(blank = True)
class Meta:
db_table = u'users'
def __str__(self):
return "%s" % (self.ldap)
def __unicode__(self):
return u'%s' % (self.ldap)
I have modified the field in phpmyadmin
This is my ModelForm
class TargetForm(forms.ModelForm):
modified = forms DateTimeField(initial = datetime.datetime.now)
def __init__(self, *args, **kwargs):
super(MMPodTargetForm, self).__init__(*args, **kwargs)
self.fields['modified'] = forms.DateTimeField(initial = datetime.datetime.now)
class Meta:
model = models.Users
I need to get current date and time autopopulated in the form, when the form loads. Tell me whats wrong in my code.

I think the error is because you're adding the auto_now_add extra argument to your form instead of to your mode. Try changing your model to the following to see if that fixes the problem (untested):
class Users(models.Model):
name = models.CharField(max_length = 100)
role = models.ForeignKey(RolesConfig, db_column = 'role')
level = models.ForeignKey(LevelConfig, db_column = 'level')
team_name = models.ForeignKey(TeamNamesConfig, db_column = 'team_name')
location = models.ForeignKey(LocationConfig, db_column = 'location')
modified = models.DateTimeField(auto_now = True)
class Meta:
db_table = u'users'
def __str__(self):
return "%s" % (self.ldap)
def __unicode__(self):
return u'%s' % (self.ldap)

Related

Django Rest Framework - Fill model field with previous entry value

I'm starting to build a REST API with Django for study purposes and I have encountered an obstacle.
I have the following model:
class ExampleModel(models.Model):
name = models.CharField(max_length = 36)
class_type = models.CharField(max_length = 10)
timestamp = models.PositiveIntegerField()
last_timestamp = models.PositiveIntegerField()
and a serializer:
class ExampleSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = ExampleModel
fields = '__all__'
read_only_fields = ['timestamp', 'last_timestamp']
def create(self, validated_data, **kwargs):
validated_data['timestamp'] = int(datetime.timestamp(datetime.now()))
#validated_data['last_timestamp'] = ...
return ExampleModel.objects.create(**validated_data)
I would like to fill the last_timestamp field with the timestamp value of the last entry that matches with the class_type of the current one.
Using the psycopg2 lib a simple solution could be:
last_entry_query = 'SELECT max(id) FROM example_table WHERE class_type = %s' % current_type
get_timestamp = 'SELECT timestamp FROM example_table WHERE id = (%s)' % last_entry_query
cur.execute(get_timestamp)
try:
ts = cur.fetchone()[0]
except:
ts = 0
and use the ts value to add to the next entry. I'm new to Django and DRF, but I assume that is a proper way to do that correctly or at least more pythonic, if anyone could help it would be amazing.

Django import export - How to skip the new rows, and only update the existed ones

When importing a file I want to skip all of the new rows that doesn't exist, and only update and change the ones that already exists, I've been trying for days to solve this problem, any ideas will help.
https://ibb.co/1Gw4Q19
also the file type is ".xls" or ".xlsx"
here's my code:
models.py:
class Author(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Category(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Book(models.Model):
name = models.CharField('Book name', max_length=100)
author = models.ForeignKey(Author, blank=True, null=True, on_delete=models.CASCADE)
author_email = models.EmailField('Author email', max_length=75, blank=True)
imported = models.BooleanField(default=False)
published = models.DateField('Published', blank=True, null=True)
price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
categories = models.ManyToManyField(Category, blank=True)
def __str__(self):
return self.name
admin.py:
class BookResource(resources.ModelResource):
class Meta:
model = Book
import_id_field = 'id'
import_id_fields = ('id',)
fields = ('id', 'name', 'price',)
skip_unchanged = True
report_skipped = True
dry_run = True
class CustomBookAdmin(ImportMixin, admin.ModelAdmin):
resource_class = BookResource
# tried to override it like so but it didn't work
def skip_row(self, instance, original):
original_id_value = getattr(original, self._meta.import_id_field)
instance_id_value = getattr(instance, self._meta.import_id_field)
if original_id_value != instance_id_value:
return True
if not self._meta.skip_unchanged:
return False
for field in self.get_fields():
try:
if list(field.get_value(instance).all()) != list(field.get_value(original).all()):
return False
except AttributeError:
if field.get_value(instance) != field.get_value(original):
return False
return True
So if you want to skip any rows in the import file which do not already exist in the database, then you can ignore any rows which don't have a pk (i.e. have not previously been persisted):
Just add the following to your BookResource sub class
def skip_row(self, instance, original):
return getattr(original, "pk") is None
I hope this works - let me know if I've misunderstood anything.
The full solution exists here
To only update existing items while ignoring any new item you can use:
# Do not import any new items. Only update records
def skip_row(self, instance, original):
if original.id:
return False
return super(BookResource, self).skip_row(instance, original)
To import only new items while preventing updates you can use:
# Only import new items. Do not update any record
def skip_row(self, instance, original):
if not original.id:
return False
return True
This assumes import_id_fields = ('id',) and resource is called BookResource

Saving / accessing fields from Class methods (Django)

Appologies for the beginner question and/or stupidity - I'm learning as I go.... I'm trying to pass a user entered url of a PubMed article to access the metadata for that article. I'm using the following code, but I cannot access anything form the save method in he 'Entry' model. For example in my html form I can display {{entry.date_added }} in a form but not {{ entry.title}}. I suspect it's a simple answer but not obvious to me. Thanks for any help.
models.py
from django.db import models
from django.contrib.auth.models import User
import pubmed_lookup
from django.utils.html import strip_tags
class Topic(models.Model):
"""Broad topic to house articles"""
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
"""Return a string representation of the model"""
return self.text
class Entry(models.Model):
"""Enter and define article from topic"""
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
pub_med_url = models.URLField(unique=True)
date_added = models.DateTimeField(auto_now_add=True)
def save(self, *args, **kwargs):
query = self.pub_med_url
email = "david.hallsworth#hotmail.com"
lookup = pubmed_lookup.PubMedLookup(query, email)
publication = pubmed_lookup.Publication(lookup)
self.title = strip_tags(publication.title)
self.authors = publication.authors
self.first_author = publication.first_author
self.last_author = publication.last_author
self.journal = publication.journal
self.year = publication.year
self.month = publication.month
self.day = publication.day
self.url = publication.url
self.citation = publication.cite()
self.mini_citation = publication.cite_mini()
self.abstract = strip_tags(publication.abstract)
super().save(*args, **kwargs)
class Meta:
verbose_name_plural = 'articles'
def __str__(self):
return "{} - {} - {} - {} [{}]".format(self.year,
self.first_author, self.journal, self.title, str(self.pmid), )
In Django ORM, you have to manually specify all fields that need to be saved. Simply saving it as self.foo = bar in the save method is stored in the Entry instance object (=in memory), but not in the database. That is, there is no persistence. Specify all the fields that need to be saved in the model and run python manage.py makemigrations,python manage.py migrate. Assigning fields to the model is actually the task of designing the relational database.
class Entry(models.Model):
"""Enter and define article from topic"""
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
pub_med_url = models.URLField(unique=True)
date_added = models.DateTimeField(auto_now_add=True)
title = models.CharField(...)
authors = models.CharField(...)
...
def assign_some_data_from_pubmed(self):
email = "david.hallsworth#hotmail.com"
lookup = pubmed_lookup.PubMedLookup(query, email)
publication = pubmed_lookup.Publication(lookup)
self.title = strip_tags(publication.title)
self.authors = publication.authors
self.first_author = publication.first_author
self.last_author = publication.last_author
self.journal = publication.journal
self.year = publication.year
self.month = publication.month
self.day = publication.day
self.url = publication.url
self.citation = publication.cite()
self.mini_citation = publication.cite_mini()
self.abstract = strip_tags(publication.abstract)
Usage:
entry = Entry(...)
entry.assign_some_data_from_pubmed()
entry.save()

Django admin does update instead of insert

My models are the following:
class Station(models.Model):
sid = models.IntegerField(primary_key=True)
uid = models.ForeignKey('User', db_column='uid', verbose_name='User')
name = models.CharField(max_length=100)
# and others...
class Meta:
managed = False
db_table = 'Stations'
class Playlist(models.Model):
plid = models.IntegerField(primary_key=True)
name = models.CharField(max_length=200)
changed = models.BooleanField(default = False)
def __unicode__(self):
return self.name
class Meta:
managed = False
db_table = 'Playlists'
class Stationplaylist(models.Model):
spid = models.IntegerField(primary_key=True, db_column='spid')
sid = models.ForeignKey(Station, db_column='sid')
plid = models.ForeignKey(Playlist, db_column='plid')
syncronized = models.BooleanField()
def __unicode__(self):
return self.plid.name
class Meta:
managed = False
db_table = 'StationsPlaylists'
unique_together=('sid', 'plid')
and I want to perform insert operation in my view:
def addPlaylist(request, app_label='webadmin', **kwargs):
# stuff...
selected_playlists = request.POST.getlist('selected_playlists[]')
current_station = request.POST.get('station')
totalPlaylists = Stationplaylist.objects.filter(sid=current_station).count()
last_spid = None
for playlist in selected_playlists:
if playlist != 'on':
if totalPlaylists==0:
last_spid=1
elif last_spid == None:
last_obj = Stationplaylist.objects.order_by('-pk')[0]
last_spid = last_obj.spid + 1
else:
last_spid += 1
Stationplaylist(last_spid, current_station, playlist, 0).save() # 0-syncronized
totalPlaylists+=1
return HttpResponse('OK')
but when I call this for, say Station#1, with 3 playlists and then I call this on another one, let it be Station#2, the playlists are simply updated. I mean, in database, their station field is updated to the Station#2.
Why is that happening and how to solve it?
Thanks in advance
You've overridden the automatic primary key and made it a pure IntegerField. This doesn't autoincrement, so every new instance gets the same default primary key.
You really shouldn't define your own primary key field unless you have a really good reason. But if you do have that good reason, you should use AutoField rather than IntegerField.

Django-celery IntegrityError Column name not unique

I have this simple model that acts like a rsync config that is used to pre fill in the fields for a celery periodic task. The first time i create a new rsync config trough the model everything is okay and a new periodic task is being created without a problem. When i try and alter certain fields that will change the task fields such as task arguments, I'm getting a "IntegrityError column name is not unique" I feel that it has something to do with the model save method but im not sure how to get it Right. anyone got some ideas?
here is the model:
from django.forms import ModelForm
from djcelery.models import IntervalSchedule
from djcelery.models import PeriodicTask, IntervalSchedule
INTERVAL=(
('every=5','period 5 minutes'),
)
class Customer(models.Model):
"""(Customer description)"""
customername = models.CharField(blank=True, max_length=30)
emailaddress = models.EmailField()
phonenumber = models.CharField(blank=True, max_length=10)
class Meta:
verbose_name_plural = "Customer"
def __unicode__(self):
return self.customername
class RsyncConfig(models.Model):
"""(RsyncConfig description)"""
cname = models.ForeignKey(Customer)
rsyncname = models.CharField(blank=True, max_length=255)
interval=models.CharField(max_length=8,choices=INTERVAL)
fromip = models.IPAddressField(blank=True)
source_dir = models.CharField(blank=True, max_length=255)
destination_dir = models.CharField(blank=True, max_length=255)
rsync_args = models.CharField(blank=True, max_length=255)
class Meta:
verbose_name_plural = "Rsync Config"
def __unicode__(self):
return self.cname.customername
And here is the admin.py form.
from django.contrib import admin
from django import forms
from djcelery.models import PeriodicTask, IntervalSchedule
from newrsync.models import Customer,RsyncConfig
class CustomerAdmin(admin.ModelAdmin):
class Meta:
model = Customer
class RsyncConfigAdminForm(forms.ModelForm):
list_display = ('customername', 'rsyncname','source_dir','destination_dir')
class Meta:
model = RsyncConfig
def __init__(self, *args, **kwargs):
super(RsyncConfigAdminForm,self).__init__(*args, **kwargs)
def save(self, commit=True):
interval = IntervalSchedule.objects.get(every=5,period="minutes")
model = super(RsyncConfigAdminForm, self).save(commit = False)
model.cname = self.cleaned_data['cname']
model.rsyncname = self.cleaned_data['rsyncname']
model.fromip = self.cleaned_data['fromip']
model.source_dir = self.cleaned_data['source_dir']
model.destination_dir = self.cleaned_data['destination_dir']
model.rsync_args = self.cleaned_data['rsync_args']
if commit:
model.save()
PeriodicTask.objects.get_or_create(
interval=interval,
task='apps.mftconfig.tasks.rsync_proc',
args=['rsync',
model.rsync_args,
model.source_dir,
model.destination_dir],
kwargs = {},
name = (model.cname," ",model.rsyncname),
enabled=False
)
return model
class RsyncConfigAdmin(admin.ModelAdmin):
form = RsyncConfigAdminForm
list_display = ('cname', 'rsyncname','source_dir','destination_dir')
admin.site.register(Customer,CustomerAdmin)
admin.site.register(RsyncConfig,RsyncConfigAdmin)
I basically ended up doing a delete of the object right before i save a new version.It's Not perfect but at least i circumvent the unique restrain in the PeriodicTask model and now let's hope it won't bite me in the ass later on.
If anyone has any suggestions, please! ;-)
class RsyncConfigAdminForm(forms.ModelForm):
list_display = ('customername','rsyncname','source_dir','destination_dir')
class Meta:
model = RsyncConfig
def __init__(self, *args, **kwargs):
super(RsyncConfigAdminForm,self).__init__(*args, **kwargs)
def save(self, commit=True):
instance = super(RsyncConfigAdminForm, self).save(commit = False)
instance.customername = self.cleaned_data['customername']
instance.rsyncname = self.cleaned_data['rsyncname']
instance.fromip = self.cleaned_data['fromip']
instance.source_dir = self.cleaned_data['source_dir']
instance.destination_dir = self.cleaned_data['destination_dir']
instance.rsync_args = self.cleaned_data['rsync_args']
interval = IntervalSchedule.objects.get(every=5,period="minutes")
p=PeriodicTask.objects.filter(name=instance.rsyncname)
p.delete()
PeriodicTask.objects.get_or_create(
interval=interval,
task='apps.mftconfig.tasks.rsync_proc',
args=['rsync',
instance.rsync_args,
instance.source_dir,
instance.destination_dir],
kwargs = {},
name = (instance.rsyncname),
enabled=True
)
if commit:
instance.save()
return instance