Прежде всего, абсолютно не используйте IntegerFields для этих значений. Это внешние ключи, вы должны использовать поле ForeignKey. Они должны называться user
и client
- обратите внимание, что вы по-прежнему можете получить доступ к базовым идентификаторам, как и раньше.
(Кроме того, нет необходимости явно объявлять поле id
; вам почти никогда не следует переопределять __init__
в модели, но особенно нет никакой точки, переопределяющей метод, который вызывает только супер метод. Просто удалите это.)
class AccessLevel(models.Model):
user = models.ForeignKey('Users', null=False, blank=False)
client = models.ForeignKey('Client', null=False, blank=False)
class Users(models.Model):
client = models.ForeignKey('Client', null=False, blank=False)
Теперь, для вашей реальной проблемы, идентификатор назначается базой данных, что происходит только после сохранения. Таким образом, вы должны создать связанный элемент после этого.
def save(self, *args, **kwargs):
super(Users, self).save(*args, **kwargs)
AccessLevel(user_id=self.id,
client_id=self.client_id).save(using='default')
print('Access Level Set for User while saving')
Другим способом создания элемента, который может быть немного более понятным, является использование средства доступа, предоставляемого внешним ключом:
self.accesslevel_set.create(client_id=self.client_id)
Наконец, это, вероятно, лучше, чем [117 ] сигнал после сохранения , а не в методе сохранения.
Только к мыслям второго Yossi's/Rich:
Я шел по этой дороге прежде и до некоторой степени жаль, что не имел. Расширяемость ре / пользовательская сериализация - необходимо быть очень осторожными. Немного легче, если Вы используете предварительно прокрученный сериализатор, такой как protobuf-сеть (который может интегрироваться непосредственно в WCF, и который разработан с расширяемостью в памяти), но не легкий.
На самом деле одно преимущество совместного использования классов состоит в том, что оно делает немного легче протестировать: так как у Вас есть то же IFoo
везде, можно дразнить это IFoo
с разумными шансами на успех. Более трудно дразнить, когда прокси принимает участие (поскольку Вы изменяете больше подвижных частей между тестовым кодом и производственным кодом).
Если тип, который Вы хотите возвратить из своего служебного вызова, не отмечен как a DataContract
затем Вы не сможете возвратить его из WCF, не предоставляя копию того же самого блока к Вашему клиентскому приложению.
using System;
using System.ServiceModel;
[ServiceContract]
interface IService
{
[OperationContract]
TimeSpan GetTimeSpan();
}
class Service : IService
{
public TimeSpan GetTimeSpan() { return DateTime.Now.TimeOfDay; }
}
Почему предыдущее кодирует работу затем? Это работает, потому что обе стороны служебного вызова имеют System.dll
таким образом, они оба знают о System.TimeSpan
введите, который является типом возврата OperationContract GetTimeSpan()
.
Вот пример с помощью a DataContract
:
using System;
using System.ServiceModel;
using System.Runtime.Serialization;
[ServiceContract]
interface IService
{
[OperationContract]
Contract GetContract();
}
[DataContract]
class Contract
{
[DataMember]
public String MyProperty { get; set; }
}
class Service : IService
{
public Contract GetContract() { return new Contract(); }
}
Теперь Вы предоставили атрибуты сериализации классу, который Вы определили (Contract
) - это позволит Вам использовать svcutil.exe
создать прокси-классы в Вашем клиентском приложении, которое будет сериализировано и отправлено службе WCF.
Теперь, если Вы хотите возвратить тип, который не является a DataContract
необходимо предоставить копию блока, содержащего тот тип к клиентскому приложению.
Одна из вещей, которые должны будут произойти, - то, что пользователь должен настроить сервисную ссылку для использования типов от DLL, а не класса, определенного прокси - http://msdn.microsoft.com/en-us/library/bb628653.aspx
Мы спустились с того пути в прошлом, и действительно проблема состоит в том, что, конечно, это два различных класса, таким образом, необходимо будет перейти по ссылке, предоставленной @Rich Агентством Рейтер;
Мы, тем не менее, научились на горьком опыте, почему это - плохая практика, поскольку она идет agains 3-й принцип SOA - "Сервисы совместно используют схему и контракт, не класс".
Конечно, проблема только не следует "правилу", установленному кем-то в какой-то момент, но что были большие причины этого, чтобы быть предложенными - мы узнали, что цена такого плотного соединения между сервисом и клиентом означает, что очень трудно выпустить любого - если сервис должен добавить другое поле к тому классу, для обслуживания другого клиента - первый клиент мог бы быть затронут; если сервис, чем потребности изменить что-то в том определении класса (для обслуживания другого клиента) - первый клиент будет снова затронут, и наоборот - клиент может влиять на жизненный цикл сервиса.
В крупных проектах это быстро становится огромной нагрузкой обслуживания.