Add M2M field using create(): Django - django-models

I have a lot of doubts about managing the M2m field, I finally got a solution to add that data to a model, but there are still some issues, give me a solution to overcome this,
class CourseListSerializer(serializers.ModelSerializer):
instructors = serializers.SerializerMethodField()
image = FileField()
keyarea = CourseKeyAreaSerializer
subject = CourseSubjectsSerializer
sections = serializers.ListField(write_only=True)
beneficiaries = serializers.ListField(write_only=True)
section = CourseSectionSerializers
beneficiary = CourseBeneficiarySerializer
def create(self, validated_data):
data = validated_data
try:
new = Course.objects.create(image=data['image'], name=data['name'], description=data['description'], is_free=data['is_free'],
keyarea=data['keyarea'], subject=data['subject'])
new.save()
beneficiary_data = data['beneficiaries']
new.beneficiary.set(*[beneficiary_data])
section_data = data['sections']
new.section.set(*[section_data])
return new
except Exception as e:
e = "invalid data"
return e
here first creating the "new" object after that to set the M2M field like
"new.beneficiary.set(*[beneficiary_data])"
but is there any way to add beneficiary and section like this
"new = Course.objects.create(image=data['image'],name=data['name'], description=data['description'],is_free=data['is_free'],....)"

Related

How can update field by overriding save method which is in another app models

I have two models Bill and Payment each with 3 fields. Here I want to update field last_price directly when user pay bill. If user pay complete amount then it would be 0. or if user not pay complete amount then remaining amount want to be save in last_price. So here I want to update amount of last_bill directly when user pay bill.
Note: Both models are in separate app
My Fields are:
BillApp/models
Bill(model.Model):
bill_no = models.IntegerField(max_length = 100,primary_key=True)
last_price = models.IntegerField()
Name = models.CharField(max_length = 20)
PaymentApp/models
Payment(model.Model):
id = models.CharField(max_length = 100,primary_key=True)
bill_no = models.ForeignKey(Bill, on_delete = SET_NULL,null=True)
total_amount = models.CharField(max_length = 10)
def save(...):
Update value of Bill.last_price
How do I update value of Bill.last_price in the save method
I tried this for update field last_price
def save(self,*args, **kwargs):
new_last_price = self.total_amount - self.bill_no.last_price
print("new_last_price : ",new_last_price)
bill_detail = Bill.objects.filter(bill_no=self.bill_no).first()
print("bill_detail : ",bill_detail)
try:
with transaction.atomic():
updated_field = bill_detail.save(update_fields = ['last_price'])
print("updated_field : ", updated_field)
super().save(*args, **kwargs)
print(Bill.objects.filter(bill_no=self.bill_no).first().last_price)
except IntegrityError:
print('Exception in save')
I getting correct output of new_last_price and bill_detail..
but updated_field display None ..
How Can I save new value in Bill?
Your save method will save the data and refresh the object instance but will not return the object instance. Use directly show last price.
bill_detail.save(update_fields = ['last_price'])
print(bill_detail.last_price)

'Anonymous user' error after passing data with Angular to Rest

I am a beginner in Angular and Rest and I have a problem. I have a form in Django template and I want to pass data with Angular, receive it with Rest and process it. Angular knows to pass (post) the data by url to:
url(r'^api/nowyPacjent/$', CreateNewPatient.as_view(), name="api_tempPatient"),
The CreateNewPatient class looks like this:
class CreateNewPatient(generics.ListCreateAPIView):
model = TempPatient
queryset = TempPatient.objects.all()
serializer_class = CreateNewPatientSerializer
and the serializer looks like this:
class CreateNewPatientSerializer(serializers.Serializer):
name = serializers.CharField(max_length=30)
surname = serializers.CharField(max_length=70)
phone = serializers.CharField(max_length=15, required=False)
age = serializers.IntegerField(max_value=99, min_value=1, required=False)
company = serializers.PrimaryKeyRelatedField(many=False, queryset=Company.objects.all())
therapyStart = serializers.DateField(required=False)
def create(self, validated_data):
if 'therapyStart' in validated_data:
therapy_start = validated_data['therapyStart']
else:
therapy_start = datetime.date.today()
if 'age' in validated_data:
patient_age = validated_data['age']
else:
patient_age = 1;
if 'phone' in validated_data:
patient_phone = validated_data['phone']
else:
patient_phone = ''
newTempPatient = TempPatient(
name = validated_data['name'],
surname = validated_data['surname'],
company = validated_data['company'],
therapyStart = therapy_start,
age = patient_age,
phone = patient_phone
)
newTempPatient.save()
newPatient = Patient(
name=validated_data['name'],
surname=validated_data['surname'],
phone=patient_phone,
age=patient_age
)
newPatient.save()
user=None
request = self.context.get('request')
if request and hasattr(request,"user"):
user=request.user
newTherapyGroup = TherapyGroup.objects.create(
start = therapy_start,
patient = newPatient,
therapist = Therapist.objects.get(user = user),
company = validated_data['company']
)
newTherapyGroup.save()
return newTempPatient
Everything is fine - after submitting the template form the patient is created - until the code tries to get logged user from the request (just after the last if statement of the serializer). Then I receive the 'AnonymousUser' error and cannot create final model instance. I've tried to pass the data to the Django views and then use the Rest's serializer. However, the error occurred again. I've searched for the answer but nothing was helpful. Please, notice that I don't want to authenticate the logged user but to get data about him.
I think the problem is that Angular somehow loose information about CSRF token and log session and that is the reason of both errors (that is only my assumption).
Below is how Angular config looks like. NewPatientCtrl is responsible for mentioned form and model is one of the form element (and it works fine).
angular.module('pacjent', ['ngMessages', 'ui.bootstrap', 'datetime'])
.constant('companyListApi','http://localhost:8000/finanse/api/list/')
.constant('tempPatientApi','http://localhost:8000/pacjent/api/nowyPacjent/')
.factory('ModelUtils', ModelUtils)
.factory('newPatientFormApi',newPatientFormApi )
.factory('companyApi', companyApi)
.factory('mySharedService', mySharedService)
.controller('PacjentCtrl', PacjentCtrl)
.controller('NewPatientCtrl', NewPatientCtrl)
.controller('ModalInstanceCtrl', ModalInstanceCtrl)
.config(function($interpolateProvider, $httpProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
})
The interesting thing is that this code works perfect on my colleague's system (Windows 7, Chrome) - the user data is gathered perfectly. However, I've tested it on three different systems (Windows 7 x64, Xubuntu 14.04, Ubuntu 14) and several browsers (Firefox, Chromium) on my PCs and the same error occurs.
Thank you a lot for any comments and advice. Sorry also for any non-professional statements.
it is because of this line:
user=request.user
# ...
therapist = Therapist.objects.get(user = user),
you are trying to get a therapist from your database with an Anynomous user in your ORM - it means a user who is not logged in.
you need is_authenticated() in your check:
if request and hasattr(request,"user") and request.user.is_authenticated():
user=request.user
newTherapyGroup = TherapyGroup.objects.create(
start = therapy_start,
patient = newPatient,
therapist = Therapist.objects.get(user=user),
company = validated_data['company']
)
newTherapyGroup.save()

How to order by nested objects fields?

I have some classes
class MarketProduct(models.Model, ObjectMarket):
_state_class = 'MarketProductState'
uuid = models.UUIDField(u'Код',
default=uuid.uuid4, editable=False)
name = models.CharField(u'Название',
max_length=255, db_index=True)
class MarketItem(models.Model, ObjectMarket):
_state_class = 'MarketItemState'
STOCK, AUCTION = 1, 2
ITEM_CHOICES = (
(STOCK, u'Сток'),
(AUCTION, u'Аукцион'),
)
product = models.ForeignKey(MarketProduct)
start_at = models.DateTimeField(u'Начало продажи')
I want to get MarketItemViewSet and use
filter_backends = (filters.OrderingFilter,`)
I send request with filed orderby by angular.
If I send orderby = start_at, all are good, but I want to send
orderby = product.id, it doesn't work.
You can try specifying product__id to perform ordering based on the id of product.
orderby = product__id
Specify ordering_fields in your viewset.
ordering_fields = ('product__id', )
As you are using django-rest-framework you have to use ordering_fields as you can see from the documentation here.Hope it helps example:
class UserListView(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
filter_backends = (filters.OrderingFilter,)
ordering_fields = ('username', 'email')
ordering = ('created_on') # for reverse ordering = ('-created_on')
If an ordering attribute is set on the view, this will be used as the default ordering.
Typically you'd instead control this by setting order_by on the initial queryset, but using the ordering parameter on the view allows you to specify the ordering in a way that it can then be passed automatically as context to a rendered template

Google App Engine - Get from repeated StructuredProperty

I have the following structures:
class UserOther(ndb.Model):
other_type = ndb.StringProperty(indexed = True)
other_data = ndb.StringProperty(indexed = False)
class User(ndb.Model):
name = ndb.StringProperty(default = "NULL", indexed = False)
email = ndb.StringProperty(default = "NULL", indexed = False)
active = ndb.BooleanProperty(default = True)
others = ndb.StructuredProperty(UserOther, repeated = True)
updated_at = ndb.DateTimeProperty(auto_now = True)
How can I use an User key id and a string for other_type(like "job") to get and be able to edit that information. I tried using the ancestor parameter, but perhaps I didn't do that correctly.
user_key = ndb.Key("User", user_id)
user = user_key.get()
other = UserOther.query(UserOther.other_type == "job", ancestor = user_key).get()
So if i print my user looks like this :
1425436064.0User(key=Key('User', 5171003185430528), active=True, email=u'NULL', name=u'NULL', others=[UserOther(other_data=u'0', other_type=u'job'), UserOther(other_data=u'0', other_type=u'times_worked'), UserOther(other_data=u'0', other_type=u'times_opened')], updated_at=datetime.datetime(2015, 3, 6, 10, 35, 24, 838078))
But if I print the job variable it is
1425436759.0None
You've misunderstood how to query for structured properties. The UserOther entity doesn't live on its own, it's part of the relevant User entity, so that's what you need to query.
The documentation explains exactly how to do this, but in summary you would do:
job = User.query(User.others.other_type == "job").get()
What I would do is get the user (by id) and then filter the 'others' in code:
user = User.get_by_id(user_key_id)
for other in user.others:
if other.other_type == 'job':
print other.other_data # do edits

user_id is not unique

i have a this thing in my views,py
def status_change(request):
if request.method == "POST":
rform = registerForm(data = request.POST)
if rform.is_valid():
register = rform.save(commit=False)
register.user = request.user
register.save()
return render_to_response('home.html')
else:
rform = registerForm()
return render_to_response('status_change.html',{'rform':rform})
when i tried to save the fields for the second time in the model it says
"column user_id is not unique"
actually i want to update it
i tried the rform.save(force_update = True)
but it didnt work
how to solve this thing.
Every time when you save form, django creates new object.
If you need to change(not create new) some object, you need first get object and then create form with instance of this object:
myobject = ...objects.get(....)
mform = MyForm(instance=myobject)
problem is solved
def status_change(request):
instance = get_object_or_404(register,pk=request.user.id)
#rest of the code here

Resources